import sys

from cpenv import api, reporter
from cpenv.cli import core
from cpenv.resolver import ResolveError


class Info(core.CLI):
    '''Show Module info'''

    usage = 'cpenv info [-h] [<modules>...]'

    def setup_parser(self, parser):
        parser.add_argument(
            'modules',
            help='Space separated list of modules.',
            nargs='*',
        )
        parser.add_argument(
            '--key',
            help=(
                'Specify the name of a key like "path" or "version". '
                'When provided this command will print the value of the key.'
            ),
            default=None,
        )
        parser.add_argument(
            '--repo',
            help='Get repo info instead of module info.',
            action='store_true',
        )
        parser.add_argument(
            '--home',
            help='Get the path to the cpenv home directory.',
            action='store_true',
        )
        parser.add_argument(
            '--cache',
            help='Get the path to the cpenv cache directory.',
            action='store_true',
        )

    def _get_key(self, obj, key):
        try:
            return eval('obj.' + key)
        except Exception as e:
            core.echo('Error: %s' % e)
            sys.exit(1)

    def run(self, args):
        if args.home:
            core.echo(api.get_home_path())
            return

        if args.cache:
            core.echo(api.get_cache_path())
            return

        # Key mode - print a key's value of a module or repo.
        if args.key:
            reporter.set_reporter(reporter.Reporter())
            if args.repo:
                objects = []
                for repo_name in args.modules:
                    repo = api.get_repo(repo_name)
                    if repo is None:
                        core.echo('Could not find repo %s' % repo_name)
                        sys.exit(1)
                    objects.append(repo)
            else:
                try:
                    objects = api.resolve(args.modules)
                except ResolveError:
                    sys.exit(1)

            value = self._get_key(objects[0], args.key)
            core.echo(value)
            return

        # Normal mode - resolve repos or modules and show info.
        core.echo()
        if args.repo:
            repos = []
            for repo_name in args.modules:
                repo = api.get_repo(repo_name)
                if repo is None:
                    core.echo('Could not find repo %s' % repo_name)
                    sys.exit(1)
                repos.append(repo)

            for repo in repos:
                core.echo(core.format_section(
                    repo.name,
                    [
                        ('name', repo.name),
                        ('path', repo.path),
                        ('type', str(type(repo))),
                        ('type_name', repo.type_name),
                    ]
                ))
                core.echo()
            return
        else:
            try:
                module_specs = api.resolve(args.modules)
            except ResolveError:
                sys.exit(1)

            core.echo()
            for spec in module_specs:
                core.echo(core.format_section(
                    spec.qual_name,
                    [
                        (k, str(v))
                        for k, v in sorted(spec._asdict().items())
                    ],
                ))
                core.echo()
            return
