# -*- coding: utf-8 -*-
#
# Copyright (c) 2016 Barcelona Supercomputing Center
# @license: https://www.gnu.org/licenses/gpl-3.0.html
# @author: see AUTHORS file

import os
import configargparse as argparse
import configparser
# from optparse import OptionParser
from mapgenerator import __version__
from mapgenerator import mg_exceptions

import logging

logging.basicConfig(level=logging.WARNING)
log = logging.getLogger(__name__)


# def list_callback(option, opt_str, value, parser):
#    setattr(parser.values, option.dest, value.split(','))
#    print("**************", value, type(value))
#    print('\toption:', repr(option))
#    print('\topt_str:', opt_str)
#    print('\tvalue:', value)
#    print('\tparser:', parser)
#    return

class ArgumentParser(object):
    def __init__(self):
        """
        Initialization of the arguments the parser can handle
        """

        try:
            self.parser = argparse.ArgumentParser(description='')
            self.parser.add_argument('-V', '--version', action='version',
                                     version=__version__,
                                     help="returns version and exit")
            self.parser.add_argument('--config',
                                     dest="config",
                                     help='specifies the config file to read'
                                     )

            self.parser.add_argument("--section",
                                     dest="section",
                                     help="config file section to read")
            # main options
            self.parser.add_argument("--srcfiles",
                                     dest="srcfiles",
                                     help="main source netCDF file")
            self.parser.add_argument("--srcvars",
                                     dest="srcvars",
                                     help="main variable")
            self.parser.add_argument("--plottype",
                                     dest="pltype",
                                     choices=['map', 'cross', 'timeseries'],
                                     help="type of plots to generate")
            #
            self.parser.add_argument("--loglevel",
                                     dest="loglevel",
                                     choices=['DEBUG',
                                              'INFO',
                                              'WARNING',
                                              'ERROR',
                                              'CRITICAL'],
                                     help="logging levelbug (default=WARNING)")

            self.parser.add_argument("--indir",
                                     dest="indir",
                                     help="directory for input file(s)")
            self.parser.add_argument("--outdir",
                                     dest="outdir",
                                     help="directory for output file(s)")
            self.parser.add_argument("--file_format",
                                     dest="filefmt",
                                     help="outputs format (default=png)")
            self.parser.add_argument("--timesteps",
                                     dest="timesteps",
                                     nargs="+",
                                     help="""timesteps (list or 'all' -
                                     default=[0])""")
            self.parser.add_argument("--bounds",
                                     dest="bounds",
                                     nargs="+",
                                     help="values bounds list (default=None)")
            self.parser.add_argument("--ticks",
                                     dest="ticks",
                                     help="colorbar ticks list (default=None)")
            self.parser.add_argument("--colors",
                                     dest="colors",
                                     help="""colors list or colormap name
                                     (default='jet'), for a list check here:
                                     https://matplotlib.org/users/colormaps.html""")
            self.parser.add_argument("--lon",
                                     dest="lon",
                                     nargs="+",
                                     help="longitude list")
            self.parser.add_argument("--lat",
                                     dest="lat",
                                     nargs="+",
                                     help="latitude list")
            self.parser.add_argument("--smooth",
                                     dest="smooth",
                                     help="plot without smoothing (default=True)")
            self.parser.add_argument("--subsetting",
                                     dest="subsetting",
                                     help="subset according to given lat/lon (default=True)")
            self.parser.add_argument("--nocontourf",
                                     dest="nocontourf",
                                     help="no contourf")
            self.parser.add_argument("--colorbar",
                                     dest="colorbar",
                                     help="toggle colorbar (default=True)")
            self.parser.add_argument("--formats",
                                     dest="formats",
                                     help="colorbar labels format (default=auto)")
            self.parser.add_argument("--extend",
                                     dest="extend",
                                     choices=['both', 'max', 'min'],
                                     help="extend colormap extremes (default='neither')")
            self.parser.add_argument("--resolution",
                                     dest="resolution",
                                     choices=['110m', '50m', '10m'],
                                     help="details level of coastlines/coutries")
            self.parser.add_argument("--dpi",
                                     dest="dpi",
                                     help="output image dpi (default=200)")
            self.parser.add_argument("--fontsize",
                                     dest="fontsize",
                                     help="title fontsize (default=12)")
            self.parser.add_argument("--continents",
                                     dest="continents",
                                     help="color to fill continents (default=None)")
            self.parser.add_argument("--coordsopts",
                                     dest="coordsopts",
                                     help="coordinates linewidth, fontsize, color (default=0.3,10,grey)")
            self.parser.add_argument("--coastsopts",
                                     dest="coastsopts",
                                     help="coastlines linewidth, color (default=0.5,grey)")
            self.parser.add_argument("--countropts",
                                     dest="countropts",
                                     help="countries linewidth, color (default=0.3,grey)")
            self.parser.add_argument("--anim",
                                     dest="anim",
                                     help="Toggle Animation (default=False)")
            self.parser.add_argument("--scatter",
                                     dest="scatter",
                                     help="data file for additional scatter plot")
            self.parser.add_argument("--contours",
                                     dest="contours",
                                     help="additional contour variable")
            self.parser.add_argument("--shapefiles",
                                     dest="shapefiles",
                                     help="additional shape files")
            self.parser.add_argument("--wind",
                                     dest="wind",
                                     help="wind source file")
            self.parser.add_argument("--windopts",
                                     dest="windopts",
                                     help="wind options")
            self.parser.add_argument("--xsize",
                                     dest="xsize",
                                     help="proportion of X dimension (between 0 and 1)")
            self.parser.add_argument("--ysize",
                                     dest="ysize",
                                     help="proportion of Y dimension (between 0 and 1)")
            self.parser.add_argument("--orig_projection",
                                     dest="orig_projection",
                                     help="origin map projection (default=PlateCarree)")
            self.parser.add_argument("--projection",
                                     dest="projection",
                                     help="map projection to draw (default=PlateCarree)")

            self.parser.add_argument("--title",
                                     dest="title",
                                     help="title of the figure")
            self.parser.add_argument("--contours_int",
                                     dest="contours_int",
                                     help="interval between contours")
            self.parser.add_argument("--contours_color",
                                     dest="contours_color",
                                     help="contours color")
            self.parser.add_argument("--contours_label",
                                     dest="contours_label",
                                     help="contours label")
#            self.parser.add_argument("--varconds",
#                              dest="varconds",
#                              help="varconds")
            self.parser.add_argument("--dimension",
                                     dest="dimension",
                                     help="dimension name and operation in the form DIMENSION,OPERATION (mean, max, min, ...) as documented in the numpy reference guide. If OPERATION is a number it will extract the correspondent element")
            self.parser.add_argument("--alpha",
                                     dest="alpha",
                                     help="""alpha value for colormap netween 0
                                     and 1 (default=1)""")
            ############
            self.parser.add_argument("--img_template",
                                     dest="img_template",
                                     help="Image template")
            self.parser.add_argument("--joint_template",
                                     dest="joint_template",
                                     help="Joint template")
            self.parser.add_argument("--nomap",
                                     dest="nomap",
                                     help="hide map")
            self.parser.add_argument("--kml",
                                     dest="kml",
                                     help="generate KML (default=False)")
            self.parser.add_argument("--kmz",
                                     dest="kmz",
                                     help="generate KMZ (default=False)")
            self.parser.add_argument("--overwrite",
                                     dest="overwrite",
                                     help="overwrite outputs (default=True)")
            self.parser.add_argument("--background",
                                     dest="background",
                                     choices=['bluemarble', 'shadedrelief', 'etopo', 'GIS'],
                                     help="background orography (default=None)")
            self.parser.add_argument("--logo",
                                     dest="logo",
                                     help="""put a logo (image path, x, y -
                                     default=None)""")
#            self.parser.add_argument("--noruntime",
#                              dest="noruntime",
#                              help="no runtime")
#            self.parser.add_argument("--limits",
#                              dest="limits",
#                              help="limits where to put an arrow in the colorbar")
#            self.parser.add_argument("-g", "--gap",
#                              action="store",
#                              dest="gap",
#                              default="",
#                              help="gap between time steps in different sources, specified as the first hour for each source")
#            self.parser.add_argument("-I", "--interval",
#                              action="store",
#                              dest="interval",
#                              default="",
#                              help="interval of time instants")
#            self.parser.add_argument("-f", "--freq",
#                              action="store",
#                              dest="freq",
#                              default="",
#                              help="frequency of time instants")
#            self.parser.add_argument("-T", "--total",
#                              action="store",
#                              dest="total",
#                              default="",
#                              help="total time instants")
#            self.parser.add_argument("-N", "--start-at",
#                              action="store",
#                              dest="start",
#                              default="",
#                              help="starting time")
#            self.parser.add_argument("--transf",
#                              action="store",
#                              dest="transf",
#                              default="",
#                              help="Transform coordinates")
#            self.parser.add_argument("--maxtitle",
#                              action="store",
#                              dest="maxtitle",
#                              default="",
#                              help="title of the max figure")
#            self.parser.add_argument("--max",
#                              action="store",
#                              dest="max",
#                              default="",
#                              help="max")

        except Exception as e:
            log.error('Unhandled exception on MapGenerator: %s' % e,
                      exc_info=True)

    # -----------------------------------------------------------------------
    # Parse arguments and preprocess
    # -----------------------------------------------------------------------
    def parse_args(self, args=None):
        """
        Parse arguments given to an executable
        :param args:
        """
        try:
            return self.parser.parse_args(args)
        except Exception as e:
            print(e)
            raise mg_exceptions.ArgumentParserException


def read_conf(section=None, fpath=None):
    """ Read configuration """

    config = configparser.RawConfigParser()
    config.read(fpath)
    if section is None:
        return config.sections()

    res = {}
    for k, v in config.items(section):
        try:
            res[k] = eval(v)
        except:
            res[k] = v
    return res


def write_conf(section, fpath, opts):
    """ Write configurations on file. """

    config = configparser.RawConfigParser()

    # check if file exists
    if os.path.exists(fpath):
        config.read(fpath)

    # check if section exists
    if not config.has_section(section):
        config.add_section(section)

    # update configuration
    for item in opts:
        val = opts[item]
        config.set(section, item, val)

    # write configuration
    with open(fpath, 'wb') as configfile:
        config.write(configfile)
