# -*- coding: utf-8 -*-
"""
ReEDS Command Line Interface
"""
import click
import logging
import os

from reV.utilities.loggers import init_mult
from reV.utilities.cli_dtypes import STR, INT
from reV.utilities.execution import SLURM, SubprocessManager

from reVX.config.wind_dirs import WindDirsConfig
from reVX.wind_dirs.prominent_wind_dirs import ProminentWindDirections

logger = logging.getLogger(__name__)


@click.group()
@click.option('--name', '-n', default='WindDirs', type=STR,
              help='Job name. Default is "WindDirs".')
@click.option('--verbose', '-v', is_flag=True,
              help='Flag to turn on debug logging. Default is not verbose.')
@click.pass_context
def main(ctx, name, verbose):
    """
    ReEDS Command Line Interface
    """
    ctx.ensure_object(dict)
    ctx.obj['NAME'] = name
    ctx.obj['VERBOSE'] = verbose


def run_local(ctx, config):
    """
    Run ProminentWindDirections locally using config

    Parameters
    ----------
    ctx : click.ctx
        click ctx object
    config : ReedsConfig
        Reeds Config object
    """
    ctx.obj['NAME'] = config.name
    ctx.invoke(local,
               powerrose_h5_fpath=config.powerrose_h5_fpath,
               excl_fpath=config.excl_fpath,
               out_dir=config.out_dir,
               agg_dset=config.agg_dset,
               tm_dset=config.tm_dset,
               resolution=config.resolution,
               excl_area=config.excl_area,
               max_workers=config.max_workers,
               chunk_point_len=config.chunk_point_len,
               log_dir=config.log_dir,
               verbose=config.verbose)


@main.command()
@click.option('--config', '-c', required=True,
              type=click.Path(exists=True),
              help='Filepath to ProminentWIndDirections config json file.')
@click.option('--verbose', '-v', is_flag=True,
              help='Flag to turn on debug logging. Default is not verbose.')
@click.pass_context
def from_config(ctx, config, verbose):
    """
    Run prominent wind directions from a config.
    """

    config = WindDirsConfig(config)

    if 'VERBOSE' in ctx.obj:
        if any((ctx.obj['VERBOSE'], verbose)):
            config._log_level = logging.DEBUG
    elif verbose:
        config._log_level = logging.DEBUG

    if config.execution_control.option == 'local':
        run_local(ctx, config)

    if config.execution_control.option == 'eagle':
        eagle(config)


@main.command()
@click.option('--powerrose_h5_fpath', '-prh5', required=True,
              type=click.Path(exists=True),
              help="Filepath to .h5 file containing powerrose data")
@click.option('--excl_fpath', '-excl', required=True,
              type=click.Path(exists=True),
              help="Filepath to exclusions h5 with techmap dataset.")
@click.option('--out_dir', '-o', required=True, type=click.Path(),
              help='Directory to dump output files')
@click.option('--agg_dset', '-ad', default='powerrose_100m', type=STR,
              help="Powerrose dataset to aggreate")
@click.option('--tm_dset', '-td', default='techmap_wtk', type=STR,
              help=("Dataset name in the techmap file containing the "
                    "exclusions-to-resource mapping data,"))
@click.option('--resolution', '-res', default=64, type=INT,
              help=("SC resolution, must be input in combination with gid. "
                    "Prefered option is to use the row / col slices to define "
                    "the SC point instead"))
@click.option('--excl_area', '-ea', default=0.0081, type=float,
              help="Area of an exclusion cell (square km)")
@click.option('--max_workers', '-mw', default=None, type=INT,
              help=("Number of cores to run summary on. None is all "
                    "available cpus"))
@click.option('--chunk_point_len', '-cpl', default=100, type=INT,
              help="Number of SC points to process on each parallel worker")
@click.option('--log_dir', '-log', default=None, type=STR,
              help='Directory to dump log files. Default is out_dir.')
@click.option('--verbose', '-v', is_flag=True,
              help='Flag to turn on debug logging. Default is not verbose.')
@click.pass_context
def local(ctx, powerrose_h5_fpath, excl_fpath, out_dir, agg_dset, tm_dset,
          resolution, excl_area, max_workers, chunk_point_len, log_dir,
          verbose):
    """
    Compute prominent wind directions on local hardware
    """
    ctx.obj['OUT_DIR'] = out_dir
    if not os.path.exists(out_dir):
        os.makedirs(out_dir)

    out_fpath = os.path.basename(powerrose_h5_fpath)
    out_fpath = out_fpath.replace('.h5', 'prominent_dir.csv')
    out_fpath = os.path.join(out_dir, out_fpath)

    if log_dir is None:
        log_dir = out_dir

    name = ctx.obj['NAME']
    if 'VERBOSE' in ctx.obj:
        verbose = any((ctx.obj['VERBOSE'], verbose))

    log_modules = [__name__, 'reVX.wind_dirs']
    init_mult(name, log_dir, modules=log_modules, verbose=verbose)

    logger.info('Running reV to ReEDS pipeline\n'
                'Outputs to be stored in: {}'.format(out_dir))

    ProminentWindDirections.run(powerrose_h5_fpath, excl_fpath,
                                agg_dset=agg_dset, tm_dset=tm_dset,
                                resolution=resolution, excl_area=excl_area,
                                max_workers=max_workers,
                                chunk_point_len=chunk_point_len,
                                out_fpath=out_fpath)


def get_node_cmd(config):
    """
    Get the node CLI call for the reVX-REEDS pipeline.

    Parameters
    ----------
    config : reVX.config.reeds.ReedsConfig
        reVX-REEDS config object.

    Returns
    -------
    cmd : str
        CLI call to submit to SLURM execution.
    """
    s = SubprocessManager.s

    args = ('-n {name} local -prh5 {pr_h5} -excl {excl_h5} -o {out_dir} '
            '-ad {agg_dset} -td {tm_dset} -res {res} -ea {excl_area} '
            '-mw {workers} -cpl {chunks} -log {log_dir} '
            .format(name=s(config.name),
                    pr_h5=s(config.powerrose_h5_fpath),
                    excl_h5=s(config.excl_fpath),
                    out_dir=s(config.dirout),
                    agg_dset=s(config.agg_dset),
                    tm_dset=s(config.tm_dset),
                    res=s(config.resolution),
                    excl_area=s(config.excl_area),
                    workers=s(config.max_workers),
                    chunks=s(config.chunk_point_len),
                    log_dir=s(config.logdir)))

    if config.log_level == logging.DEBUG:
        args += '-v '

    cmd = 'python -m reVX.wind_dirs.wind_dirs_cli {}'.format(args)
    logger.debug('Submitting the following cli call:\n\t{}'.format(cmd))
    return cmd


def eagle(config):
    """
    Run reVX-REEDS on Eagle HPC.

    Parameters
    ----------
    config : reVX.config.reeds.ReedsConfig
        reVX-REEDS config object.
    """

    cmd = get_node_cmd(config)
    name = config.name
    log_dir = config.logdir
    stdout_path = os.path.join(log_dir, 'stdout/')

    logger.info('Running reVX-REEDS pipeline on Eagle with '
                'node name "{}"'.format(name))
    slurm = SLURM(cmd, alloc=config.execution_control.alloc,
                  memory=config.execution_control.node_mem,
                  walltime=config.execution_control.walltime,
                  feature=config.execution_control.feature,
                  name=name, stdout_path=stdout_path,
                  conda_env=config.execution_control.conda_env,
                  module=config.execution_control.module)
    if slurm.id:
        msg = ('Kicked off prominent wind direction calculation "{}" '
               '(SLURM jobid #{}) on Eagle.'
               .format(name, slurm.id))
    else:
        msg = ('Was unable to kick off prominent wind direction calculation '
               '"{}". Please see the stdout error messages'
               .format(name))

    click.echo(msg)
    logger.info(msg)


if __name__ == '__main__':
    try:
        main(obj={})
    except Exception:
        logger.exception('Error running Prominent Wind Directions CLI')
        raise
