#!/usr/bin/env python3
from collections import OrderedDict

import click
import logging

from anvil.etl.extract import extract
from anvil.etl.transform import transform
from anvil.etl.utility import utility
from anvil.etl.load import load
from anvil.etl import DEFAULT_OUTPUT_PATH
import pkg_resources
import yaml
from click_loglevel import LogLevel


LOG_FORMAT = '%(asctime)s %(name)s %(levelname)-8s %(message)s'
logger = logging.getLogger('etl-cli')


def read_config(path=None):
    """Read config, if no path, read from installed resource."""

    if not path:
        resource_package = 'anvil.etl'   
        path = 'utilities/config.yaml'  # Do not use os.path.join()
        config_file = pkg_resources.resource_stream(resource_package, path)    
    else:
        config_file = open(path) 

    config = yaml.load(config_file, Loader=yaml.SafeLoader)
    assert sorted(config.keys()) == ['consortiums', 'mapping'], f"Config missing expected keys. {config.keys()} "

    return config


class NaturalOrderGroup(click.Group):

    def __init__(self, name=None, commands=None, **attrs):
        super(NaturalOrderGroup, self).__init__(
            name=name, commands=None, **attrs)
        if commands is None:
            commands = OrderedDict()
        elif not isinstance(commands, OrderedDict):
            commands = OrderedDict(commands)
        self.commands = commands

    def list_commands(self, ctx):
        return self.commands.keys()


@click.group(cls=NaturalOrderGroup)
@click.option("-l", "--log-level", type=LogLevel(), default=logging.INFO)
@click.option('--output_path', default=DEFAULT_OUTPUT_PATH, help='output path for working files and output.', show_default=True)
@click.option('--config_path', default=None, help='path to config file override.', show_default=True)
@click.pass_context
def cli(ctx, log_level, output_path,config_path):
    """ETL: extract from terra workspaces, google buckets and gen3; transform to FHIR; load to google  Healthcare API."""
    # ensure that ctx.obj exists and is a dict
    # set root logging
    logging.basicConfig(level=log_level, format=LOG_FORMAT)
    ctx.ensure_object(dict)
    ctx.obj['log_level'] = log_level
    ctx.obj['output_path'] = output_path
    ctx.obj['config'] = read_config(config_path)


if __name__ == '__main__':
    cli.add_command(extract)
    cli.add_command(transform)
    cli.add_command(load)
    cli.add_command(utility)
    cli()
