# SPDX-License-Identifier: Apache-2.0
# Copyright 2013-2017 The Meson development team
# Copyright © 2021-2023 Intel Corporation

from __future__ import annotations

"""Dependency finders for the Qt framework."""

import abc
import re
import os
import typing as T

from .base import DependencyException, DependencyMethods
from .configtool import ConfigToolDependency
from .detect import packages
from .framework import ExtraFrameworkDependency
from .pkgconfig import PkgConfigDependency
from .factory import DependencyFactory
from .. import mlog
from .. import mesonlib

if T.TYPE_CHECKING:
    from ..compilers import Compiler
    from ..envconfig import MachineInfo
    from ..environment import Environment
    from ..dependencies import MissingCompiler


def _qt_get_private_includes(mod_inc_dir: str, module: str, mod_version: str) -> T.List[str]:
    # usually Qt5 puts private headers in /QT_INSTALL_HEADERS/module/VERSION/module/private
    # except for at least QtWebkit and Enginio where the module version doesn't match Qt version
    # as an example with Qt 5.10.1 on linux you would get:
    # /usr/include/qt5/QtCore/5.10.1/QtCore/private/
    # /usr/include/qt5/QtWidgets/5.10.1/QtWidgets/private/
    # /usr/include/qt5/QtWebKit/5.212.0/QtWebKit/private/

    # on Qt4 when available private folder is directly in module folder
    # like /usr/include/QtCore/private/
    if int(mod_version.split('.')[0]) < 5:
        return []

    private_dir = os.path.join(mod_inc_dir, mod_version)
    # fallback, let's try to find a directory with the latest version
    if os.path.isdir(mod_inc_dir) and not os.path.exists(private_dir):
        dirs = [filename for filename in os.listdir(mod_inc_dir)
                if os.path.isdir(os.path.join(mod_inc_dir, filename))]

        for dirname in sorted(dirs, reverse=True):
            if len(dirname.split('.')) == 3:
                private_dir = dirname
                break
    return [private_dir, os.path.join(private_dir, 'Qt' + module)]


def get_qmake_host_bins(qvars: T.Dict[str, str]) -> str:
    # Prefer QT_HOST_BINS (qt5, correct for cross and native compiling)
    # but fall back to QT_INSTALL_BINS (qt4)
    if 'QT_HOST_BINS' in qvars:
        return qvars['QT_HOST_BINS']
    return qvars['QT_INSTALL_BINS']


def get_qmake_host_libexecs(qvars: T.Dict[str, str]) -> T.Optional[str]:
    if 'QT_HOST_LIBEXECS' in qvars:
        return qvars['QT_HOST_LIBEXECS']
    return qvars.get('QT_INSTALL_LIBEXECS')


def _get_modules_lib_suffix(version: str, info: 'MachineInfo', is_debug: bool) -> str:
    """Get the module suffix based on platform and debug type."""
    suffix = ''
    if info.is_windows():
        if is_debug:
            suffix += 'd'
        if version.startswith('4'):
            suffix += '4'
    if info.is_darwin():
        if is_debug:
            suffix += '_debug'
    if mesonlib.version_compare(version, '>= 5.14.0'):
        if info.is_android():
            if info.cpu_family == 'x86':
                suffix += '_x86'
            elif info.cpu_family == 'x86_64':
                suffix += '_x86_64'
            elif info.cpu_family == 'arm':
                suffix += '_armeabi-v7a'
            elif info.cpu_family == 'aarch64':
                suffix += '_arm64-v8a'
            else:
                mlog.warning(f'Android target arch "{info.cpu_family}"" for Qt5 is unknown, '
                             'module detection may not work')
    return suffix


class QtExtraFrameworkDependency(ExtraFrameworkDependency):
    def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any], qvars: T.Dict[str, str], language: T.Optional[str] = None):
        super().__init__(name, env, kwargs, language=language)
        self.mod_name = name[2:]
        self.qt_extra_include_directory = qvars['QT_INSTALL_HEADERS']

    def get_compile_args(self, with_private_headers: bool = False, qt_version: str = "0") -> T.List[str]:
        if self.found():
            mod_inc_dir = os.path.join(self.framework_path, 'Headers')
            args = ['-I' + mod_inc_dir]
            if with_private_headers:
                args += ['-I' + dirname for dirname in _qt_get_private_includes(mod_inc_dir, self.mod_name, qt_version)]
            if self.qt_extra_include_directory:
                args += ['-I' + self.qt_extra_include_directory]
            return args
        return []


class _QtBase:

    """Mixin class for shared components between PkgConfig and Qmake."""

    link_args: T.List[str]
    clib_compiler: T.Union['MissingCompiler', 'Compiler']
    env: 'Environment'
    libexecdir: T.Optional[str] = None
    version: str

    def __init__(self, name: str, kwargs: T.Dict[str, T.Any]):
        self.name = name
        self.qtname = name.capitalize()
        self.qtver = name[-1]
        if self.qtver == "4":
            self.qtpkgname = 'Qt'
        else:
            self.qtpkgname = self.qtname

        self.private_headers = T.cast('bool', kwargs.get('private_headers', False))

        self.requested_modules = mesonlib.stringlistify(mesonlib.extract_as_list(kwargs, 'modules'))
        if not self.requested_modules:
            raise DependencyException('No ' + self.qtname + '  modules specified.')

        self.qtmain = T.cast('bool', kwargs.get('main', False))
        if not isinstance(self.qtmain, bool):
            raise DependencyException('"main" argument must be a boolean')

    def _link_with_qt_winmain(self, is_debug: bool, libdir: T.Union[str, T.List[str]]) -> bool:
        libdir = mesonlib.listify(libdir)  # TODO: shouldn't be necessary
        base_name = self.get_qt_winmain_base_name(is_debug)
        qt_winmain = self.clib_compiler.find_library(base_name, self.env, libdir)
        if qt_winmain:
            self.link_args.append(qt_winmain[0])
            return True
        return False

    def get_qt_winmain_base_name(self, is_debug: bool) -> str:
        return 'qtmaind' if is_debug else 'qtmain'

    def get_exe_args(self, compiler: 'Compiler') -> T.List[str]:
        # Originally this was -fPIE but nowadays the default
        # for upstream and distros seems to be -reduce-relocations
        # which requires -fPIC. This may cause a performance
        # penalty when using self-built Qt or on platforms
        # where -fPIC is not required. If this is an issue
        # for you, patches are welcome.
        return compiler.get_pic_args()

    def log_details(self) -> str:
        return f'modules: {", ".join(sorted(self.requested_modules))}'


class QtPkgConfigDependency(_QtBase, PkgConfigDependency, metaclass=abc.ABCMeta):

    """Specialization of the PkgConfigDependency for Qt."""

    def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
        _QtBase.__init__(self, name, kwargs)

        # Always use QtCore as the "main" dependency, since it has the extra
        # pkg-config variables that a user would expect to get. If "Core" is
        # not a requested module, delete the compile and link arguments to
        # avoid linking with something they didn't ask for
        PkgConfigDependency.__init__(self, self.qtpkgname + 'Core', env, kwargs)
        if 'Core' not in self.requested_modules:
            self.compile_args = []
            self.link_args = []

        for m in self.requested_modules:
            mod = PkgConfigDependency(self.qtpkgname + m, self.env, kwargs, language=self.language)
            if not mod.found():
                self.is_found = False
                return
            if self.private_headers:
                qt_inc_dir = mod.get_variable(pkgconfig='includedir')
                mod_private_dir = os.path.join(qt_inc_dir, 'Qt' + m)
                if not os.path.isdir(mod_private_dir):
                    # At least some versions of homebrew don't seem to set this
                    # up correctly. /usr/local/opt/qt/include/Qt + m_name is a
                    # symlink to /usr/local/opt/qt/include, but the pkg-config
                    # file points to /usr/local/Cellar/qt/x.y.z/Headers/, and
                    # the Qt + m_name there is not a symlink, it's a file
                    mod_private_dir = qt_inc_dir
                mod_private_inc = _qt_get_private_includes(mod_private_dir, m, mod.version)
                for directory in mod_private_inc:
                    mod.compile_args.append('-I' + directory)
            self._add_sub_dependency([lambda: mod])

        if self.env.machines[self.for_machine].is_windows() and self.qtmain:
            # Check if we link with debug binaries
            debug_lib_name = self.qtpkgname + 'Core' + _get_modules_lib_suffix(self.version, self.env.machines[self.for_machine], True)
            is_debug = False
            for arg in self.get_link_args():
                if arg == f'-l{debug_lib_name}' or arg.endswith(f'{debug_lib_name}.lib') or arg.endswith(f'{debug_lib_name}.a'):
                    is_debug = True
                    break
            libdir = self.get_variable(pkgconfig='libdir')
            if not self._link_with_qt_winmain(is_debug, libdir):
                self.is_found = False
                return

        self.bindir = self.get_pkgconfig_host_bins(self)
        if not self.bindir:
            # If exec_prefix is not defined, the pkg-config file is broken
            prefix = self.get_variable(pkgconfig='exec_prefix')
            if prefix:
                self.bindir = os.path.join(prefix, 'bin')

        self.libexecdir = self.get_pkgconfig_host_libexecs(self)

    @staticmethod
    @abc.abstractmethod
    def get_pkgconfig_host_bins(core: PkgConfigDependency) -> T.Optional[str]:
        pass

    @staticmethod
    @abc.abstractmethod
    def get_pkgconfig_host_libexecs(core: PkgConfigDependency) -> T.Optional[str]:
        pass

    @abc.abstractmethod
    def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
        pass

    def log_info(self) -> str:
        return 'pkg-config'


class QmakeQtDependency(_QtBase, ConfigToolDependency, metaclass=abc.ABCMeta):

    """Find Qt using Qmake as a config-tool."""

    version: str
    version_arg = '-v'

    def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
        _QtBase.__init__(self, name, kwargs)
        self.tool_name = f'qmake{self.qtver}'
        self.tools = [f'qmake{self.qtver}', f'qmake-{self.name}', 'qmake']

        # Add additional constraints that the Qt version is met, but preserve
        # any version requirements the user has set as well. For example, if Qt5
        # is requested, add "">= 5, < 6", but if the user has ">= 5.6", don't
        # lose that.
        kwargs = kwargs.copy()
        _vers = mesonlib.listify(kwargs.get('version', []))
        _vers.extend([f'>= {self.qtver}', f'< {int(self.qtver) + 1}'])
        kwargs['version'] = _vers

        ConfigToolDependency.__init__(self, name, env, kwargs)
        if not self.found():
            return

        # Query library path, header path, and binary path
        stdo = self.get_config_value(['-query'], 'args')
        qvars: T.Dict[str, str] = {}
        for line in stdo:
            line = line.strip()
            if line == '':
                continue
            k, v = line.split(':', 1)
            qvars[k] = v
        # Qt on macOS uses a framework, but Qt for iOS/tvOS does not
        xspec = qvars.get('QMAKE_XSPEC', '')
        if self.env.machines.host.is_darwin() and not any(s in xspec for s in ['ios', 'tvos']):
            mlog.debug("Building for macOS, looking for framework")
            self._framework_detect(qvars, self.requested_modules, kwargs)
            # Sometimes Qt is built not as a framework (for instance, when using conan pkg manager)
            # skip and fall back to normal procedure then
            if self.is_found:
                return
            else:
                mlog.debug("Building for macOS, couldn't find framework, falling back to library search")
        incdir = qvars['QT_INSTALL_HEADERS']
        self.compile_args.append('-I' + incdir)
        libdir = qvars['QT_INSTALL_LIBS']
        # Used by qt.compilers_detect()
        self.bindir = get_qmake_host_bins(qvars)
        self.libexecdir = get_qmake_host_libexecs(qvars)

        # Use the buildtype by default, but look at the b_vscrt option if the
        # compiler supports it.
        is_debug = self.env.coredata.get_option(mesonlib.OptionKey('buildtype')) == 'debug'
        if mesonlib.OptionKey('b_vscrt') in self.env.coredata.options:
            if self.env.coredata.options[mesonlib.OptionKey('b_vscrt')].value in {'mdd', 'mtd'}:
                is_debug = True
        modules_lib_suffix = _get_modules_lib_suffix(self.version, self.env.machines[self.for_machine], is_debug)

        for module in self.requested_modules:
            mincdir = os.path.join(incdir, 'Qt' + module)
            self.compile_args.append('-I' + mincdir)

            if module == 'QuickTest':
                define_base = 'QMLTEST'
            elif module == 'Test':
                define_base = 'TESTLIB'
            else:
                define_base = module.upper()
            self.compile_args.append(f'-DQT_{define_base}_LIB')

            if self.private_headers:
                priv_inc = self.get_private_includes(mincdir, module)
                for directory in priv_inc:
                    self.compile_args.append('-I' + directory)
            libfiles = self.clib_compiler.find_library(
                self.qtpkgname + module + modules_lib_suffix, self.env,
                mesonlib.listify(libdir)) # TODO: shouldn't be necessary
            if libfiles:
                libfile = libfiles[0]
            else:
                mlog.log("Could not find:", module,
                         self.qtpkgname + module + modules_lib_suffix,
                         'in', libdir)
                self.is_found = False
                break
            self.link_args.append(libfile)

        if self.env.machines[self.for_machine].is_windows() and self.qtmain:
            if not self._link_with_qt_winmain(is_debug, libdir):
                self.is_found = False

    def _sanitize_version(self, version: str) -> str:
        m = re.search(rf'({self.qtver}(\.\d+)+)', version)
        if m:
            return m.group(0).rstrip('.')
        return version

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

    @abc.abstractmethod
    def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
        pass

    def _framework_detect(self, qvars: T.Dict[str, str], modules: T.List[str], kwargs: T.Dict[str, T.Any]) -> None:
        libdir = qvars['QT_INSTALL_LIBS']

        # ExtraFrameworkDependency doesn't support any methods
        fw_kwargs = kwargs.copy()
        fw_kwargs.pop('method', None)
        fw_kwargs['paths'] = [libdir]

        for m in modules:
            fname = 'Qt' + m
            mlog.debug('Looking for qt framework ' + fname)
            fwdep = QtExtraFrameworkDependency(fname, self.env, fw_kwargs, qvars, language=self.language)
            if fwdep.found():
                self.compile_args.append('-F' + libdir)
                self.compile_args += fwdep.get_compile_args(with_private_headers=self.private_headers,
                                                            qt_version=self.version)
                self.link_args += fwdep.get_link_args()
            else:
                self.is_found = False
                break
        else:
            self.is_found = True
            # Used by self.compilers_detect()
            self.bindir = get_qmake_host_bins(qvars)
            self.libexecdir = get_qmake_host_libexecs(qvars)

    def log_info(self) -> str:
        return 'qmake'


class Qt6WinMainMixin:

    def get_qt_winmain_base_name(self, is_debug: bool) -> str:
        return 'Qt6EntryPointd' if is_debug else 'Qt6EntryPoint'


class Qt4ConfigToolDependency(QmakeQtDependency):

    def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
        return []


class Qt5ConfigToolDependency(QmakeQtDependency):

    def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
        return _qt_get_private_includes(mod_inc_dir, module, self.version)


class Qt6ConfigToolDependency(Qt6WinMainMixin, QmakeQtDependency):

    def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
        return _qt_get_private_includes(mod_inc_dir, module, self.version)


class Qt4PkgConfigDependency(QtPkgConfigDependency):

    @staticmethod
    def get_pkgconfig_host_bins(core: PkgConfigDependency) -> T.Optional[str]:
        # Only return one bins dir, because the tools are generally all in one
        # directory for Qt4, in Qt5, they must all be in one directory. Return
        # the first one found among the bin variables, in case one tool is not
        # configured to be built.
        applications = ['moc', 'uic', 'rcc', 'lupdate', 'lrelease']
        for application in applications:
            try:
                return os.path.dirname(core.get_variable(pkgconfig=f'{application}_location'))
            except mesonlib.MesonException:
                pass
        return None

    def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
        return []

    @staticmethod
    def get_pkgconfig_host_libexecs(core: PkgConfigDependency) -> str:
        return None


class Qt5PkgConfigDependency(QtPkgConfigDependency):

    @staticmethod
    def get_pkgconfig_host_bins(core: PkgConfigDependency) -> str:
        return core.get_variable(pkgconfig='host_bins')

    @staticmethod
    def get_pkgconfig_host_libexecs(core: PkgConfigDependency) -> str:
        return None

    def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
        return _qt_get_private_includes(mod_inc_dir, module, self.version)


class Qt6PkgConfigDependency(Qt6WinMainMixin, QtPkgConfigDependency):

    def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any]):
        super().__init__(name, env, kwargs)
        if not self.libexecdir:
            mlog.debug(f'detected Qt6 {self.version} pkg-config dependency does not '
                       'have proper tools support, ignoring')
            self.is_found = False

    @staticmethod
    def get_pkgconfig_host_bins(core: PkgConfigDependency) -> str:
        return core.get_variable(pkgconfig='bindir')

    @staticmethod
    def get_pkgconfig_host_libexecs(core: PkgConfigDependency) -> str:
        # Qt6 pkg-config for Qt defines libexecdir from 6.3+
        return core.get_variable(pkgconfig='libexecdir')

    def get_private_includes(self, mod_inc_dir: str, module: str) -> T.List[str]:
        return _qt_get_private_includes(mod_inc_dir, module, self.version)


packages['qt4'] = qt4_factory = DependencyFactory(
    'qt4',
    [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL],
    pkgconfig_class=Qt4PkgConfigDependency,
    configtool_class=Qt4ConfigToolDependency,
)

packages['qt5'] = qt5_factory = DependencyFactory(
    'qt5',
    [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL],
    pkgconfig_class=Qt5PkgConfigDependency,
    configtool_class=Qt5ConfigToolDependency,
)

packages['qt6'] = qt6_factory = DependencyFactory(
    'qt6',
    [DependencyMethods.PKGCONFIG, DependencyMethods.CONFIG_TOOL],
    pkgconfig_class=Qt6PkgConfigDependency,
    configtool_class=Qt6ConfigToolDependency,
)
