#!/usr/bin/env python

from __future__ import print_function

"""
indicator-definitions
~~~~~~~~~~~~~~~~~
Creates a CSV with indicator definitions (names of dataelement.catoptioncombo, constants, orgunitgroups)
"""

import argparse
import csv
import os
import sys

from core.core import Dhis


def replace_definitions(definition, obj_map):
    """replace numerator/denominators with readable objects"""
    for i, j in obj_map.items():
        definition = definition.replace(i, obj_map[i]['desc'])
    return definition

#
def object_map():
    """get all relevant objects from the server and put it in a single dictionary"""
    object_map = {}
    print("Building object mappings...")

    params1 = {'paging': False}
    resp1 = dhis.get(endpoint='indicatorTypes', params=params1)
    for elem in resp1['indicatorTypes']:
        object_map[elem['id']] = {'desc': elem['displayName']}

    params2 = {'fields': 'id,name,value', 'paging': False}
    resp2 = dhis.get(endpoint='constants', params=params2)
    for elem in resp2['constants']:
        object_map[elem['id']] = {'desc': "Name: {} - Value: {}".format(elem['name'], elem['value'])}

    params3 = {'fields': 'id,name,organisationUnits', 'paging': False}
    resp3 = dhis.get(endpoint='organisationUnitGroups', params=params3)
    for elem in resp3['organisationUnitGroups']:
        object_map[elem['id']] = {'desc': "Name: {} - OU Size: {}".format(elem['name'], len(elem['organisationUnits']))}

    params4 = {'fields': 'id,name', 'paging': False}
    resp4 = dhis.get(endpoint='dataElements', params=params4)
    for elem in resp4['dataElements']:
        object_map[elem['id']] = {'desc': elem['name']}

    params5 = {'fields': 'id,name', 'paging': False}
    resp5 = dhis.get(endpoint='categoryOptionCombos', params=params5)
    for elem in resp5['categoryOptionCombos']:
        object_map[elem['id']] = {'desc': elem['name']}

    return object_map


parser = argparse.ArgumentParser(description="Create CSV with indicator definitions")
parser.add_argument('-s', dest='server', action='store', help="Server, e.g. play.dhis2.org/demo", required=True)
parser.add_argument('-f', dest='indicator_filter', action='store', help="Indicator filter", required=False)
parser.add_argument('-u', dest='username', action='store', help="DHIS2 username", required=True)
parser.add_argument('-p', dest='password', action='store', help="DHIS2 password", required=True)

args = parser.parse_args()

# handling of UTF-8 names for all Python versions
try:
    reload(sys)
    sys.setdefaultencoding('utf8') # Python 2.7
except NameError:
    try:
        from importlib import reload # Python 3.4+
        reload(sys)
    except ImportError:
        from imp import reload  # Python 3.0 - 3.3
        reload(sys)

dhis = Dhis(server=args.server, username=args.username, password=args.password, debug_flag=args.debug)

if args.indicator_filter:
    params = {
        'paging': False,
        'fields': 'id,name,shortName,description,denominatorDescription,numeratorDescription,numerator,denominator,annualized,decimals,indicatorType',
        'filter': args.indicator_filter
    }
else:
    params = {
        'paging': False,
        'fields': 'id,name,shortName,description,denominatorDescription,numeratorDescription,numerator,denominator,annualized,decimals,indicatorType'
    }

indicators = dhis.get(endpoint='indicators', params=params)
print("Analyzing {} indicators from {}".format(len(indicators['indicators']), args.server))

object_map = object_map()
file_name = 'indicator-descriptions-{}.csv'.format(args.server.replace('https://', '').replace('.', '_'))
path = os.path.dirname(os.path.abspath(__file__))
file_path = "{}/{}".format(path, file_name)

with open(file_name, 'w', newline='') as csvfile:
    writer = csv.writer(csvfile, delimiter=';', quoting=csv.QUOTE_MINIMAL)
    writer.writerow(
        ['id', 'name', 'shortName', 'numerator', 'num_desc', 'denominator', 'den_desc', 'annualized', 'indicatorType',
         'decimals'])

    for ind in indicators['indicators']:
        num = replace_definitions(ind['numerator'], object_map)
        den = replace_definitions(ind['denominator'], object_map)

        ind_type_desc = object_map[ind['indicatorType']['id']].get('desc')
        writer.writerow([ind['id'], ind['name'], ind['shortName'], num, ind.get('numeratorDescription', None), den,
                         ind.get('denominatorDescription', None), ind.get('annualized', None), ind_type_desc,
                         ind.get('decimals', 'default')])

    print("File written to {}".format(file_path))
