#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (C) Joseph Areeda (2015)
#
# This file is part of GWpy.
#
# GWpy is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GWpy is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GWpy.  If not, see <http://www.gnu.org/licenses/>.
#
"""Command line interface to GWpy plotting functions
"""
import time
prog_start = time.time()    # verbose enough times major ops

import sys
from importlib import import_module
import argparse
import os
from gwpy import __version__

__author__ = 'joseph areeda'
__email__ = 'joseph.areeda@ligo.org'


VERBOSE = 3     # 0 = errors only, 1 = Warnings, 2 = INFO, >2 DEBUG >=5 ALL

if sys.version < '2.7':
    raise ImportError("Python versions older than 2.7 are not supported.")


# ---needed to generate help messages---
class CliHelpFormatter(argparse.ArgumentDefaultsHelpFormatter):
    def __init__(self, *args, **kwargs):
        kwargs.setdefault('indent_increment', 4)
        super(CliHelpFormatter, self).__init__(*args, **kwargs)
# ----

# Products are classes that implement a specific plot
# This is a list of those class names, module names
# This is the only list of all products
PRODUCTS = [
        'TimeSeries',
        'Coherence',
        'Spectrum',
        'Spectrogram',
        'Coherencegram',
        'Qtransform'
]

parser = argparse.ArgumentParser(formatter_class=CliHelpFormatter,
                                 description=__doc__, prog='gwpy-plot')

# set the argument parser to act as the parent
parentparser = argparse.ArgumentParser(add_help=False)

# These arguments apply to all commands
parentparser.add_argument('-v', '--verbose', action='count', default=1,
                          help='increase verbose output')
parentparser.add_argument('-s', '--silent', default=False,
                          help='show only fatal errors')

# subparsers are dependent on which action is chosen
subparsers = parser.add_subparsers(
    dest='mode', title='Actions',
    description='Select one of the following actions:')

# dictionary for subparsers
sp = dict()
actions = dict()

# -------------------------
# Add the actions and their parameters to the subparsers

# Add the subparsers for each plot product
for product in PRODUCTS:
    mod_name = product.lower()
    mod = import_module('gwpy.cli.%s' % mod_name)
    class_ = getattr(mod, product)
    prod = class_()

    # the action is the command line argument for which lot which class to call
    action = prod.get_action()
    sp[product] = subparsers.add_parser(action, help=prod.__doc__,
                                        parents=[parentparser])
    # the operation is the name of the action
    sp[product].set_defaults(func=action)
    prod.init_cli(sp[product])
    actions[action] = prod
# -----------------------------------------------------------------------------
# Run

if __name__ == '__main__':
    try:
        # if we're launched with minimum or no environment
        # variables make some guesses
        if len(os.getenv('HOME', '')) == 0:
            os.environ['HOME'] = '/tmp/'

        # if launched from a terminal with no display
        if len(os.getenv('DISPLAY', '')) == 0:
            import matplotlib
            matplotlib.use('Agg')

        # parse the command line
        args = parser.parse_args()
        if args.silent:
            VERBOSE = 0
        else:
            VERBOSE = args.verbose
        if not args.mode:
            raise RuntimeError("Must specify action. "
                               "Please try again with --help.")
        prod = actions[args.func]
        prod.log(2, ('%s called' % args.func))

        # apply custom styling
        if args.style:
            from matplotlib import pyplot
            pyplot.style.use(args.style)

        # Products get a chance to massage args
        # eg: q-transform takes gps & search to provide
        #     start, duration and epoch, xmin...
        prod.post_arg(args)

        setup_time = time.time() - prog_start
        prod.log(2, 'Setup time %.1f sec' % setup_time)

        # generate the plot
        result_code = prod.makePlot(args, parser)

        # If they requested interactive mode and run from ipython
        # this makes it easier
        if prod.is_interactive:
            # import pyplot so that user has access to it
            from matplotlib import pyplot as plt  # pylint: disable=unused-import
            plot = prod.plot
            # pull raw data and plotted results from product for their use
            timeseries = prod.timeseries
            result = prod.result
            print('Raw data is in "timeseries", plotted data is in "result"')
            ax = plot.gca()
        run_time = time.time() - prog_start
        prod.log(1, 'Program run time: %.1f' % run_time)
        if result_code > 0:
            sys.exit(result_code)
    except:
        # standard exception reporting wasn't working
        typ, msg, trcbk = sys.exc_info()
        import traceback

        if 'SystemExit' not in str(typ):
            traceback.print_tb(trcbk)
            print ('Error: %s, %s' % (typ, msg))
        sys.exit(3)
