import argparse
import os
import sys

from cfg_checker.common.exception import ConfigException, \
    CommandTypeNotSupportedException, CheckerException


class MyParser(argparse.ArgumentParser):
    def error(self, message):
        sys.stderr.write('Error: {0}\n\n'.format(message))
        self.print_help()


def get_skip_args(args):
    if hasattr(args, "skip_nodes"):
        _skip = getattr(args, "skip_nodes")
        if _skip:
            _skip = _skip.split(',')
    else:
        _skip = None
    if hasattr(args, "skip_nodes_file"):
        _skip_file = getattr(args, "skip_nodes_file")
    else:
        _skip_file = None
    return _skip, _skip_file


def get_arg(args, str_arg):
    _attr = getattr(args, str_arg)
    if _attr:
        return _attr
    else:
        _c = args.command if hasattr(args, 'command') else ''
        _t = args.type if hasattr(args, 'type') else ''
        raise ConfigException(
            "Argument '{}' not found executing: mcp-check {} {}".format(
                str_arg,
                _c,
                _t
            )
        )


def get_path_arg(path):
    if os.path.exists(path):
        return path
    else:
        raise ConfigException("'{}' not exists".format(path))


def get_network_map_type_and_filename(args):
    if args.html or args.text:
        if args.html and args.text:
            raise ConfigException("Multuple report types not supported")
        if args.html is not None:
            return 'html', args.html
        if args.text is not None:
            return 'text', args.text
    else:
        return 'console', None


def get_package_report_type_and_filename(args):
    if args.html or args.csv:
        if args.html and args.csv:
            raise ConfigException("Multuple report types not supported")
        if args.html is not None:
            return 'html', args.html
        if args.csv is not None:
            return 'csv', args.csv
    else:
        raise ConfigException("Report type and filename not set")


def check_supported_env(target_env, args, config):
    def _raise_type_not_supported():
        raise CommandTypeNotSupportedException(
                "'{}' -> '{}' is not supported on any of "
                "the currently detected environments: "
                "{}".format(
                    args.command,
                    args.type,
                    ",".join(config.detected_envs))
        )

    def _check_target_vs_used(_tenv):
        if not hasattr(args, 'use_env'):
            return _tenv
        elif args.use_env == _tenv or not args.use_env:
            return _tenv
        else:
            raise CommandTypeNotSupportedException(
                    "'{}' -> '{}' is not supported "
                    "for selected env of '{}'".format(
                        args.command,
                        args.type,
                        args.use_env
                        )
            )

    if isinstance(target_env, list):
        _set = set(config.detected_envs).intersection(set(target_env))
        if len(_set) < 1:
            _raise_type_not_supported()
        if len(_set) > 1:
            if not hasattr(args, 'use_env'):
                raise CheckerException(
                    "Multiple envs detected: {}, use --use-env option".format(
                        ",".join(list(_set))
                    )
                )
            elif args.use_env and args.use_env in _set:
                return args.use_env
            else:
                _raise_type_not_supported()
        else:
            return _check_target_vs_used(list(_set)[0])
    elif isinstance(target_env, str):
        if target_env not in config.detected_envs:
            _raise_type_not_supported()
        else:
            return _check_target_vs_used(target_env)
    else:
        raise CheckerException(
            "Unexpected target env type '{}' in '{}' -> '{}'".format(
                target_env,
                args.command,
                args.type,
            )
        )
