#!/usr/bin/env python

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

import argparse
import csv
import sys

from src.dhis.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"""
    uid_mapping = {}
    dhis.log.info("Building object UID mappings...")

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

    params2 = {'fields': 'id,name,value', 'paging': False}
    resp2 = dhis.get(endpoint='constants', params=params2)
    for elem in resp2['constants']:
        uid_mapping[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']:
        uid_mapping[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']:
        uid_mapping[elem['id']] = {'desc': elem['name']}

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

    params6 = {'fields': 'id,name', 'paging': False}
    resp6 = dhis.get(endpoint='programs', params=params6)
    for elem in resp6['programs']:
        uid_mapping[elem['id']] = {'desc': elem['name']}

    params7 = {'fields': 'id,name', 'paging': False}
    resp7 = dhis.get(endpoint='programIndicators', params=params7)
    for elem in resp7['programIndicators']:
        uid_mapping[elem['id']] = {'desc': elem['name']}

    params8 = {'fields': 'id,name', 'paging': False}
    resp8 = dhis.get(endpoint='trackedEntityAttributes', params=params8)
    for elem in resp8['trackedEntityAttributes']:
        uid_mapping[elem['id']] = {'desc': elem['name']}

    return uid_mapping

parser = argparse.ArgumentParser(description="Create CSV with indicator definitions/expressions")
parser.add_argument('-s', dest='server', action='store', help="DHIS2 server URL without /api/, e.g. -s='play.dhis2.org/demo'", required=True)
parser.add_argument('-f', dest='indicator_filter', action='store', help="Indicator filter, e.g. -f='name:^like:HIV'", 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)
parser.add_argument('-v', dest='api_version', action='store', required=False, type=int,
                    help='DHIS2 API version e.g. -v=24')
parser.add_argument('-d', dest='debug', action='store_true', default=False, required=False,
                    help="Debug flag - writes more info to log file")

args = parser.parse_args()

dhis = Dhis(server=args.server, username=args.username, password=args.password, debug_flag=args.debug,
            api_version=args.api_version)
dhis.log.startinfo(__file__)

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)
dhis.log.debug("Fetched indicators: {}".format(indicators))
if len(indicators) == 0:
    if args.indicator_filter:
        dhis.log.info("No indicators fetched - wrong filter?")
        sys.exit()
    else:
        dhis.log.info("No indicators found - are there any?")
        sys.exit()
dhis.log.info("Analyzing {} indicators from {}".format(len(indicators['indicators']), args.server))

object_mapping = object_map()
file_name = 'indicator-descriptions-{}.csv'.format(
    args.server.replace('https://', '').replace('.', '_').replace('/', '_'))

with open(file_name, 'w') 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_mapping)
        den = replace_definitions(ind['denominator'], object_mapping)
        dhis.log.debug("Replaced numerators: {}".format(num))
        dhis.log.debug("Replaced denominators: {}".format(den))

        ind_type_desc = object_mapping[ind['indicatorType']['id']].get('desc')
        row = [
            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')
        ]
        writer.writerow(row)

    dhis.log.info("File written to {}".format(file_name))
