#! /usr/bin/python3
#
# Copyright (c) 2017-2018 - Adjacent Link LLC, Bridgewater, New Jersey
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
#   notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
#   notice, this list of conditions and the following disclaimer in
#   the documentation and/or other materials provided with the
#   distribution.
# * Neither the name of Adjacent Link LLC nor the names of its
#   contributors may be used to endorse or promote products derived
#   from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# See toplevel COPYING for more information.

from __future__ import absolute_import, division, print_function

import sys
import os
import traceback
from argparse import ArgumentParser
from letce2.engine.build import *

try:
    import ConfigParser as configparser
except:
    import configparser

plugins = {}

# create the top-level parser
argument_parser = ArgumentParser()

argument_parser.add_argument('-m',
                             '--manifest',
                             type=str,
                             metavar='FILE',
                             default='manifest',
                             help='manifest file [default: %(default)s].')

argument_parser.add_argument('--include-filter',
                             action='append',
                             type=str,
                             metavar='REGEX',
                             help='include only nodes matching filter.')

argument_parser.add_argument('--exclude-filter',
                             action='append',
                             type=str,
                             metavar='REGEX',
                             help='exlcude nodes matching filter.')

argument_parser.add_argument('--include-file',
                             type=str,
                             metavar='FILE',
                             help='include only nodes listed in file.')

argument_parser.add_argument('--exclude-file',
                             type=str,
                             metavar='FILE',
                             help='exlcude nodes listed in file.')

subparsers = argument_parser.add_subparsers(help='sub-command help')

subparser_build = subparsers.add_parser('build',
                                        help='create all experiment input files.')

subparser_build.add_argument('experiment-config',
                             nargs='+',
                             type=str,
                             help='configuration file.')

subparser_build.set_defaults(subcommand='build')

subparser_clean = subparsers.add_parser('clean',
                                        help='clean experiment input files.')

subparser_clean.set_defaults(subcommand='clean')

if os.path.exists('letce2.cfg'):
    letce2_parser = configparser.ConfigParser()
    letce2_parser.read('letce2.cfg')
    for section in letce2_parser.sections():
        # import the plugin module
        m = __import__(letce2_parser.get(section,'module'),
                       fromlist=['*'])

        # get the plugin class
        PluginClass = getattr(m,'Plugin')

        plugins[section] = PluginClass(section,subparsers)

ns = argument_parser.parse_args()

args = vars(ns)

if 'subcommand' not in args:
    print('missing subcommand: See `letce2 -h` for more information.',
          file=sys.stderr)
    exit(1)

if args['subcommand'] == 'build':
    nodes = build_configuration(args['experiment-config'],
                                args['include_filter'],
                                args['exclude_filter'],
                                args['include_file'],
                                args['exclude_file'],
                                args['manifest'],
                                None)

elif args['subcommand'] == 'clean':
    nodes_include,nodes_exclude = nodes_from_manifest(args['include_filter'],
                                                      args['exclude_filter'],
                                                      args['include_file'],
                                                      args['exclude_file'],
                                                      args['manifest'])
    clean_configuration(nodes_include,
                        args['manifest'])

    if nodes_exclude:
        nodes_to_manifest(nodes_exclude,
                          args['manifest'])

elif args['subcommand'] in plugins:
    nodes_include,nodes_exlude = nodes_from_manifest(args['include_filter'],
                                                     args['exclude_filter'],
                                                     args['include_file'],
                                                     args['exclude_file'],
                                                     args['manifest'])

    plugins[args['subcommand']].process(nodes_include,
                                        nodes_exlude,
                                        args)
