#    Copyright 2013 - 2017 Mirantis, Inc.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from __future__ import print_function

import argparse
import sys
import yaml

from reclass_tools import walk_models


class Shell(object):
    def __init__(self, args):
        self.args = args
        self.params = self.get_params()

    def str2bool(self, v):
        return v.lower() in ("true")

    def execute(self):
        command_name = 'do_{}'.format(self.params.command.replace('-', '_'))
        command_method = getattr(self, command_name)
        command_method()

    def do_get_key(self):
        walk_models.remove_reclass_parameter(
            self.params.path,
            self.params.key_name,
            verbose=self.params.verbose,
            pretend=True)

    def do_add_key(self):
        # Try convert to digits
        if self.params.str:
            add_val = str(self.params.add_value)
        else:
            try:
                add_val = int(self.params.add_value)
            except ValueError:
                # Try convert to float
                try:
                    add_val = float(self.params.add_value)
                except ValueError:
                    try:
                        # Try convert to list
                        if type(eval(self.params.add_value)) == list:
                            add_val = eval(self.params.add_value)
                    except (SyntaxError, NameError):
                      add_val = self.params.add_value

        walk_models.add_reclass_parameter(
            self.params.path,
            self.params.key_name,
            add_val,
            verbose=self.params.verbose,
            merge=self.params.merge)

    def do_add_bool_key(self):
        add_val = self.str2bool(self.params.add_value)

        walk_models.add_reclass_parameter(
            self.params.path,
            self.params.key_name,
            add_val,
            verbose=self.params.verbose,
            merge=self.params.merge)

    def do_del_key(self):
        walk_models.remove_reclass_parameter(
            self.params.path,
            self.params.key_name,
            verbose=self.params.verbose,
            pretend=False)

    def do_list_params(self):
        results = walk_models.get_all_reclass_params(
            self.params.path,
            verbose=self.params.verbose)
        print(yaml.dump(results, width=255))

    def do_list_domains(self):
        try:
            from reclass_tools import reclass_models
        except ImportError:
            sys.exit("Please run this tool on the salt-master node "
                     "with installed 'reclass'")
        inventory = reclass_models.inventory_list()
        reclass_storage = reclass_models.reclass_storage(inventory=inventory)
        print('\n'.join(sorted(reclass_storage.keys())))

    def do_list_nodes(self):
        try:
            from reclass_tools import reclass_models
        except ImportError:
            sys.exit("Please run this tool on the salt-master node "
                     "with installed 'reclass'")

        inventory = reclass_models.inventory_list(domain=self.params.domain)
        vcp_nodes = reclass_models.vcp_list(domain=self.params.domain,
                                            inventory=inventory)
        vcp_node_names = ['{0}.{1}'.format(name, domain)
                          for name, domain in vcp_nodes]

        if self.params.vcp_only:
            print('\n'.join(sorted(vcp_node_names)))
        elif self.params.non_vcp_only:
            print('\n'.join(sorted((node_name for node_name in inventory.keys()
                                    if node_name not in vcp_node_names))))
        else:
            print('\n'.join(sorted(inventory.keys())))

    def do_trace_key(self):
        try:
            from reclass_tools import reclass_models
        except ImportError:
            sys.exit("Please run this tool on the salt-master node "
                     "with installed 'reclass'")
        reclass_models.trace_key(key=self.params.key_name,
                                 domain=self.params.domain,
                                 node=self.params.node)

    def do_show_context(self):
        try:
            from reclass_tools import create_inventory
        except ImportError:
            sys.exit("Please run this tool on the salt-master node "
                     "with installed 'reclass'")

        current_underlay_context = create_inventory.create_inventory_context(
            domain=self.params.domain, keys=self.params.keys)

        print(yaml.dump(current_underlay_context, default_flow_style=False,
                        width=255))

    def do_render(self):
        from reclass_tools import render

        if not self.params.template_dir or not self.params.output_dir \
                or not self.params.contexts:
            sys.exit("Missing parameters, see: reclass-tools render -h")

        render.render_dir(template_dir=self.params.template_dir,
                          output_dir=self.params.output_dir,
                          contexts=self.params.contexts,
                          env_name=self.params.env_name)

    def do_merge_context(self):
        content = yaml.load(open(self.params.yaml).read(), yaml.SafeLoader)
        walk_models.merge_dict_to_reclass(
            self.params.path,
            content)

    def get_params(self):

        verbose_parser = argparse.ArgumentParser(add_help=False)
        verbose_parser.add_argument('--verbose', dest='verbose',
                                    action='store_const', const=True,
                                    help='Show verbosed output', default=False)

        merge_parser = argparse.ArgumentParser(add_help=False)
        merge_parser.add_argument('--merge', dest='merge',
                                  action='store_const', const=True,
                                  help='Merge value to list or dict',
                                  default=False)

        as_str_parser = argparse.ArgumentParser(add_help=False)
        as_str_parser.add_argument('--str', dest='str',
                                   action='store_const', const=True,
                                   help='Use value as plain string',
                                   default=False)

        key_parser = argparse.ArgumentParser(add_help=False)
        key_parser_help = (
            'Key name to find in reclass model files, for example:'
            ' parameters.linux.network.interface')
        key_parser.add_argument('key_name', help=key_parser_help, default=None)

        keys_parser = argparse.ArgumentParser(add_help=False)
        keys_parser.add_argument(
            'keys',
            help='Key names to find in reclass model files', nargs='*')

        add_value_parser = argparse.ArgumentParser(add_help=False)
        add_value_parser.add_argument(
            'add_value',
            help=('Value to add to the reclass model files, can be in the '
                  'inline YAML format'))

        yaml_parser = argparse.ArgumentParser(add_help=False)
        yaml_parser.add_argument(
            'yaml',
            help='Path to YAML file with extra context')

        path_parser = argparse.ArgumentParser(add_help=False)
        path_parser.add_argument(
            'path',
            help='Path to search for *.yml files.', nargs='+')

        domain_parser = argparse.ArgumentParser(add_help=False)
        domain_parser.add_argument(
            '--domain', '-d', dest='domain',
            help=('Show only the nodes which names are ended with the '
                  'specified domain, for example: example.local'))

        node_parser = argparse.ArgumentParser(add_help=False)
        node_parser.add_argument(
            '--node', '-n', dest='node',
            help=('Show only the specified node, for example: '
                  'ctl01.example.local'))

        env_name_parser = argparse.ArgumentParser(add_help=False)
        env_name_parser.add_argument(
            '--env-name', '-e', dest='env_name',
            help=("Name of the 'environment' to create or use"),
            default=None)

        vcp_only_parser = argparse.ArgumentParser(add_help=False)
        vcp_only_parser.add_argument(
            '--vcp-only', dest='vcp_only',
            action='store_const', const=True,
            help=('Show only VCP nodes (present in '
                  'parameters.salt.control.cluster.internal.node)'),
            default=False)

        non_vcp_only_parser = argparse.ArgumentParser(add_help=False)
        non_vcp_only_parser.add_argument(
            '--non-vcp-only', dest='non_vcp_only',
            action='store_const', const=True,  default=False,
            help=('Show only non-VCP nodes (absent in '
                  'parameters.salt.control.cluster.internal.node)'))

        render_parser = argparse.ArgumentParser(add_help=False)
        render_parser.add_argument(
            '--template-dir', '-t', dest='template_dir',
            help=('Coockiecutter-based template directory'))
        render_parser.add_argument(
            '--output-dir', '-o', dest='output_dir',
            help=('Path to the directory where the rendered '
                  'template will be placed'))
        render_parser.add_argument(
            '--context', '-c', dest='contexts', action='append',
            help=('YAML/JSON files with context data to render '
                  'the template'))

        parser = argparse.ArgumentParser(
            description="Manage virtual environments. "
                        "For additional help, use with -h/--help option")
        subparsers = parser.add_subparsers(title="Operation commands",
                                           help='available commands',
                                           dest='command')

        subparsers.add_parser('get-key',
                              parents=[key_parser, path_parser,
                                       verbose_parser],
                              help="Find a key in YAMLs found in <path>",
                              description=("Get a key collected from "
                                           "different YAMLs"))
        subparsers.add_parser('add-key',
                              parents=[key_parser, add_value_parser,
                                       path_parser, verbose_parser,
                                       merge_parser, as_str_parser],
                              help="Add a key in YAMLs found in <path>",
                              description=("Add a key to "
                                           "different YAMLs"))

        subparsers.add_parser('add-bool-key',
                              parents=[key_parser, add_value_parser,
                                       path_parser, verbose_parser,
                                       merge_parser],
                              help="Add a bool key in YAMLs found in <path>. "
                                   "True/False string values are converted to bool",
                              description=("Add a bool key collected to "
                                           "different YAMLs"))

        subparsers.add_parser('del-key',
                              parents=[key_parser, path_parser,
                                       verbose_parser],
                              help="Delete a key from YAMLs found in <path>",
                              description="Delete a key from different YAMLs")
        subparsers.add_parser('list-params',
                              parents=[path_parser, verbose_parser],
                              help=("Collect all options for "
                                    "'parameters._params' keys from YAMLs "
                                    "found in <path>"))
        subparsers.add_parser('list-nodes',
                              parents=[domain_parser, vcp_only_parser,
                                       non_vcp_only_parser],
                              help=("List nodes that are available for "
                                    "reclass. Use on salt-master node only!"))
        subparsers.add_parser('list-domains',
                              help=("List domains that are available from "
                                    "reclass models. Use on salt-master "
                                    "node only!"))
        subparsers.add_parser('show-context',
                              parents=[domain_parser, keys_parser],
                              help=("Show domain nodes with rendered content "
                                    "for specified keys. Use on salt-master "
                                    "node for already generated inventory "
                                    "only!"))
        subparsers.add_parser('trace-key',
                              parents=[domain_parser, node_parser, key_parser],
                              help=("Use 'reclass' to merge the model and "
                                    "show all the classes where the "
                                    "specified key is overwritten, and updated"
                                    " values during merging and after "
                                    "interpolation. "
                                    "Use on salt-master node only!"))
        subparsers.add_parser('render',
                              parents=[render_parser, env_name_parser],
                              help=("Render cookiecutter template using "
                                    "multiple metadata sources"))
        subparsers.add_parser('merge-context',
                              parents=[yaml_parser, path_parser],
                              help=("Merge nested content from YAML file "
                                    "to specified reclass models"))

        if len(self.args) == 0:
            self.args = ['-h']
        return parser.parse_args(self.args)


def main(args=None):
    if args is None:
        args = sys.argv[1:]

    shell = Shell(args)
    shell.execute()
