# 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.optstore.get_value_for('buildtype') == 'debug'
        if 'b_vscrt' in self.env.coredata.optstore:
            if self.env.coredata.optstore.get_value_for('b_vscrt') 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,
)
