#    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
        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)

        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],
                              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()
