# Copyright (C) 2012 Anaconda, Inc
# SPDX-License-Identifier: BSD-3-Clause
"""CLI implementation for `conda compare`.

Compare the packages in an environment with the packages listed in an environment file.
"""
import logging
import os
from os.path import abspath, expanduser, expandvars

from conda_env import specs

from ..base.context import context
from ..core.prefix_data import PrefixData
from ..exceptions import EnvironmentLocationNotFound, SpecNotFound
from ..gateways.connection.session import CONDA_SESSION_SCHEMES
from ..gateways.disk.test import is_conda_environment
from ..models.match_spec import MatchSpec
from .common import stdout_json

log = logging.getLogger(__name__)


def get_packages(prefix):
    if not os.path.isdir(prefix):
        raise EnvironmentLocationNotFound(prefix)

    return sorted(
        PrefixData(prefix, pip_interop_enabled=True).iter_records(),
        key=lambda x: x.name,
    )


def _get_name_tuple(pkg):
    return pkg.name, pkg


def _to_str(pkg):
    return f"{pkg.name}=={pkg.version}={pkg.build}"


def compare_packages(active_pkgs, specification_pkgs):
    output = []
    res = 0
    ok = True
    for pkg in specification_pkgs:
        pkg_spec = MatchSpec(pkg)
        name = pkg_spec.name
        if name in active_pkgs:
            if not pkg_spec.match(active_pkgs[name]):
                ok = False
                output.append(
                    "{} found but mismatch. Specification pkg: {}, Running pkg: {}".format(
                        name, pkg, _to_str(active_pkgs[name])
                    )
                )
        else:
            ok = False
            output.append(f"{name} not found")
    if ok:
        output.append(
            "Success. All the packages in the \
specification file are present in the environment \
with matching version and build string."
        )
    else:
        res = 1
    return res, output


def execute(args, parser):
    prefix = context.target_prefix
    if not is_conda_environment(prefix):
        raise EnvironmentLocationNotFound(prefix)

    try:
        url_scheme = args.file.split("://", 1)[0]
        if url_scheme in CONDA_SESSION_SCHEMES:
            filename = args.file
        else:
            filename = abspath(expanduser(expandvars(args.file)))

        spec = specs.detect(name=args.name, filename=filename, directory=os.getcwd())
        env = spec.environment

        if args.prefix is None and args.name is None:
            args.name = env.name
    except SpecNotFound:
        raise

    active_pkgs = dict(map(_get_name_tuple, get_packages(prefix)))
    specification_pkgs = []
    if "conda" in env.dependencies:
        specification_pkgs = specification_pkgs + env.dependencies["conda"]
    if "pip" in env.dependencies:
        specification_pkgs = specification_pkgs + env.dependencies["pip"]

    exitcode, output = compare_packages(active_pkgs, specification_pkgs)

    if context.json:
        stdout_json(output)
    else:
        print("\n".join(map(str, output)))

    return exitcode
