# SPDX-License-Identifier: Apache-2.0
# Copyright 2013-2021 The Meson development team

from __future__ import annotations

from .base import ExternalDependency, DependencyException, DependencyTypeName
from ..mesonlib import listify, Popen_safe, Popen_safe_logged, split_args, version_compare, version_compare_many
from ..programs import find_external_program
from .. import mlog
import re
import typing as T

if T.TYPE_CHECKING:
    from ..environment import Environment
    from ..interpreter.type_checking import PkgConfigDefineType
    from .base import DependencyObjectKWs


class ConfigToolDependency(ExternalDependency):

    """Class representing dependencies found using a config tool.

    Takes the following extra keys in kwargs that it uses internally:
    :tools List[str]: A list of tool names to use
    :version_arg str: The argument to pass to the tool to get its version
    :skip_version str: The argument to pass to the tool to ignore its version
        (if ``version_arg`` fails, but it may start accepting it in the future)
        Because some tools are stupid and don't accept --version
    :returncode_value int: The value of the correct returncode
        Because some tools are stupid and don't return 0
    """

    tools: T.Optional[T.List[str]] = None
    tool_name: T.Optional[str] = None
    version_arg = '--version'
    skip_version: T.Optional[str] = None
    allow_default_for_cross = False
    __strip_version = re.compile(r'^[0-9][0-9.]+')
    type_name = DependencyTypeName('config-tool')

    def __init__(self, name: str, environment: 'Environment', kwargs: DependencyObjectKWs, exclude_paths: T.Optional[T.List[str]] = None):
        super().__init__(name, environment, kwargs)
        # You may want to overwrite the class version in some cases
        self.tools = listify(kwargs.get('tools', self.tools))
        if not self.tool_name:
            self.tool_name = self.tools[0]
        if 'version_arg' in kwargs:
            self.version_arg = kwargs['version_arg']

        req_version = kwargs.get('version', [])
        tool, version = self.find_config(req_version, kwargs.get('returncode_value', 0), exclude_paths=exclude_paths)
        self.config = tool
        self.is_found = self.report_config(version, req_version)
        if not self.is_found:
            self.config = None
            return
        self.version = version

    def _sanitize_version(self, version: str) -> str:
        """Remove any non-numeric, non-point version suffixes."""
        m = self.__strip_version.match(version)
        if m:
            # Ensure that there isn't a trailing '.', such as an input like
            # `1.2.3.git-1234`
            return m.group(0).rstrip('.')
        return version

    def _check_and_get_version(self, tool: T.List[str], returncode: int) -> T.Tuple[bool, T.Union[str, None]]:
        """Check whether a command is valid and get its version"""
        p, out = Popen_safe(tool + [self.version_arg])[:2]
        valid = True
        if p.returncode != returncode:
            if self.skip_version:
                # maybe the executable is valid even if it doesn't support --version
                p = Popen_safe(tool + [self.skip_version])[0]
                if p.returncode != returncode:
                    valid = False
            else:
                valid = False
        version = self._sanitize_version(out.strip())
        return valid, version

    def find_config(self, versions: T.List[str], returncode: int = 0, exclude_paths: T.Optional[T.List[str]] = None) \
            -> T.Tuple[T.Optional[T.List[str]], T.Optional[str]]:
        """Helper method that searches for config tool binaries in PATH and
        returns the one that best matches the given version requirements.
        """
        exclude_paths = [] if exclude_paths is None else exclude_paths
        best_match: T.Tuple[T.Optional[T.List[str]], T.Optional[str]] = (None, None)
        for potential_bin in find_external_program(
                self.env, self.for_machine, self.tool_name,
                self.tool_name, self.tools, exclude_paths=exclude_paths,
                allow_default_for_cross=self.allow_default_for_cross):
            if not potential_bin.found():
                continue
            tool = potential_bin.get_command()
            try:
                valid, version = self._check_and_get_version(tool, returncode)
            except (FileNotFoundError, PermissionError):
                continue
            if not valid:
                continue

            # Some tools, like pcap-config don't supply a version, but also
            # don't fail with --version, in that case just assume that there is
            # only one version and return it.
            if not version:
                return (tool, None)
            if versions:
                is_found = version_compare_many(version, versions)[0]
                # This allows returning a found version without a config tool,
                # which is useful to inform the user that you found version x,
                # but y was required.
                if not is_found:
                    tool = None
            if best_match[1]:
                if version_compare(version, '> {}'.format(best_match[1])):
                    best_match = (tool, version)
            else:
                best_match = (tool, version)

        return best_match

    def report_config(self, version: T.Optional[str], req_version: T.List[str]) -> bool:
        """Helper method to print messages about the tool."""

        found_msg: T.List[T.Union[str, mlog.AnsiDecorator]] = [mlog.bold(self.tool_name), 'found:']

        if self.config is None:
            found_msg.append(mlog.red('NO'))
            if version is not None and req_version:
                found_msg.append(f'found {version!r} but need {req_version!r}')
            elif req_version:
                found_msg.append(f'need {req_version!r}')
        else:
            found_msg += [mlog.green('YES'), '({})'.format(' '.join(self.config)), version]

        mlog.log(*found_msg)

        return self.config is not None

    def get_config_value(self, args: T.List[str], stage: str, required: bool = False) -> T.List[str]:
        p, out, err = Popen_safe_logged(self.config + args)
        if p.returncode != 0:
            if self.required or required:
                raise DependencyException(f'Could not generate {stage} for {self.name}.\n{err}')
            return []
        return split_args(out)

    def get_variable_args(self, variable_name: str) -> T.List[str]:
        return [f'--{variable_name}']

    def get_variable(self, *, cmake: T.Optional[str] = None, pkgconfig: T.Optional[str] = None,
                     configtool: T.Optional[str] = None, internal: T.Optional[str] = None,
                     system: T.Optional[str] = None, default_value: T.Optional[str] = None,
                     pkgconfig_define: PkgConfigDefineType = None) -> str:
        if configtool:
            p, out, _ = Popen_safe(self.config + self.get_variable_args(configtool))
            if p.returncode == 0:
                variable = out.strip()
                mlog.debug(f'Got config-tool variable {configtool} : {variable}')
                return variable
        if default_value is not None:
            return default_value
        raise DependencyException(f'Could not get config-tool variable and no default provided for {self!r}')
