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, nofail=False):
    _attr = getattr(args, str_arg)
    if _attr:
        return _attr
    else:
        if nofail:
            return None
        _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, 'force_env_type'):
            return _tenv
        elif args.force_env_type == _tenv or not args.force_env_type:
            return _tenv
        else:
            raise CommandTypeNotSupportedException(
                    "'{}' -> '{}' is not supported "
                    "for selected env of '{}'".format(
                        args.command,
                        args.type,
                        args.force_env_type
                        )
            )

    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, 'force_env_type'):
                raise CheckerException(
                    "Multiple envs detected: {}, use --use-env option".format(
                        ",".join(list(_set))
                    )
                )
            elif args.force_env_type and args.force_env_type in _set:
                return args.force_env_type
            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,
            )
        )
