#!/usr/bin/env python3
#
# Copyright (C) 2012, 2013, 2014 Ben Elliston
# Copyright (C) 2014, 2015 The University of New South Wales
#
# This file 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.

"""Replay runs from a text file of generators."""
import argparse
import json
import re
import sys
import numpy as np

from gooey import Gooey
import nemo
from nemo import costs
from nemo import scenarios
from nemo import utils


@Gooey(program_name="NEMO replay tool",
       richtext_controls=True,
       show_success_modal=False,
       monospaced_font=True,
       optional_cols=1)
def process_options():
    """Process command line options."""
    parser = argparse.ArgumentParser(description='Bug reports via via https://nemo.ozlabs.org')
    parser.add_argument("-f", type=str, help='filename of results file', metavar='FILE',
                        default='results.json')
    parser.add_argument("-v", action="count", help='verbosity level', default=0)
    parser.add_argument("-t", "--transmission", action="store_true", help="show region exchanges")
    parser.add_argument("-x", "--plot", action="store_true", help='producing a balancing plot')
    parser.add_argument("--spills", action="store_true", help='plot surplus generation')
    parser.add_argument("--no-legend", action="store_false", help="hide legend")
    return parser.parse_args()


def run_one(bundle):
    """Run a single simulation."""
    options = bundle['options']

    context = nemo.Context()
    context.nsp_limit = options['nsp_limit']
    assert 0 <= context.nsp_limit <= 1

    scenario = options['supply_scenario']
    try:
        scenarios.supply_scenarios[scenario](context)
    except KeyError:
        print('unknown scenario: %s' % scenario)
        sys.exit(1)
    print('scenario', scenario)

    # Apply each demand modifier argument (if any) in the given order.
    for arg in options['demand_modifier']:
        scenarios.demand_switch(arg)(context)

    try:
        cost_class = costs.cost_scenarios[options['costs']]
    except KeyError:
        print('unknown cost class: %s' % options['costs'])
        sys.exit(1)
    context.costs = cost_class(options['discount_rate'],
                               options['coal_price'], options['gas_price'],
                               options['ccs_storage_costs'])
    context.costs.carbon = options['carbon_price']

    capacities = bundle['parameters']
    context.set_capacities(capacities)

    context.track_exchanges = args.transmission
    context.verbose = args.v > 1
    nemo.run(context)
    context.verbose = args.v > 0
    print(context)
    if args.transmission:
        np.set_printoptions(precision=3)
        x = context.exchanges.max(axis=0)
        print(np.array_str(x, precision=1, suppress_small=True))
        with open('exchanges.json', 'w') as f:
            json.dump(x.tolist(), f)
    print()

    if args.plot:  # pragma: no cover
        utils.plot(context, spills=args.spills, showlegend=args.no_legend)


args = process_options()
with open(args.f) as resultsfile:
    for line in resultsfile:
        if re.search(r'^\s*$', line):
            continue
        if re.search(r'^\s*#', line):
            print(line, end=' ')
            continue
        try:
            jsonBundle = json.loads(line)
        except ValueError:
            print('skipping malformed input:', line)
            continue
        run_one(jsonBundle)
