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

from __future__ import annotations

from .base import DependencyTypeName, ExternalDependency, DependencyException
from ..mesonlib import MesonException, Version
from .. import mlog
from pathlib import Path
import typing as T

if T.TYPE_CHECKING:
    from ..environment import Environment
    from .base import DependencyObjectKWs

class ExtraFrameworkDependency(ExternalDependency):
    system_framework_paths: T.Optional[T.List[str]] = None

    type_name = DependencyTypeName('extraframeworks')

    def __init__(self, name: str, env: 'Environment', kwargs: DependencyObjectKWs) -> None:
        paths = kwargs.get('paths', [])
        super().__init__(name, env, kwargs)
        # Full path to framework directory
        self.framework_path: T.Optional[str] = None
        if not self.clib_compiler:
            raise DependencyException('No C-like compilers are available')
        if self.system_framework_paths is None:
            try:
                self.system_framework_paths = self.clib_compiler.find_framework_paths()
            except MesonException as e:
                if 'non-clang' in str(e):
                    # Apple frameworks can only be found (and used) with the
                    # system compiler. It is not available so bail immediately.
                    self.is_found = False
                    return
                raise
        self.detect(name, paths)

    def detect(self, name: str, paths: T.List[str]) -> None:
        if not paths:
            paths = self.system_framework_paths
        for p in paths:
            mlog.debug(f'Looking for framework {name} in {p}')
            # We need to know the exact framework path because it's used by the
            # Qt5 dependency class, and for setting the include path. We also
            # want to avoid searching in an invalid framework path which wastes
            # time and can cause a false positive.
            framework_path = self._get_framework_path(p, name)
            if framework_path is None:
                continue
            framework_name = framework_path.stem
            # We want to prefer the specified paths (in order) over the system
            # paths since these are "extra" frameworks.
            # For example, Python2's framework is in /System/Library/Frameworks and
            # Python3's framework is in /Library/Frameworks, but both are called
            # Python.framework. We need to know for sure that the framework was
            # found in the path we expect.
            allow_system = p in self.system_framework_paths
            args = self.clib_compiler.find_framework(framework_name, [p], allow_system)
            if args is None:
                continue
            self.link_args = args
            self.framework_path = framework_path.as_posix()
            # The search is done case-insensitively, so the found name may differ
            # from the one that was requested. Setting the name ensures the correct
            # one is used when linking on case-sensitive filesystems.
            self.name = framework_name
            self.compile_args = ['-F' + self.framework_path]
            # We need to also add -I includes to the framework because all
            # cross-platform projects such as OpenGL, Python, Qt, GStreamer,
            # etc do not use "framework includes":
            # https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPFrameworks/Tasks/IncludingFrameworks.html
            incdir = self._get_framework_include_path(framework_path)
            if incdir:
                self.compile_args += ['-idirafter' + incdir]
            self.is_found = True
            return

    def _get_framework_path(self, path: str, name: str) -> T.Optional[Path]:
        p = Path(path)
        lname = name.lower()
        for d in p.glob('*.framework/'):
            if lname == d.stem.lower():
                return d
        return None

    def _get_framework_latest_version(self, path: Path) -> str:
        versions: T.List[Version] = []
        for each in path.glob('Versions/*'):
            # macOS filesystems are usually case-insensitive
            if each.name.lower() == 'current':
                continue
            versions.append(Version(each.name))
        if len(versions) == 0:
            # most system frameworks do not have a 'Versions' directory
            return 'Headers'
        return 'Versions/{}/Headers'.format(sorted(versions)[-1]._s)

    def _get_framework_include_path(self, path: Path) -> T.Optional[str]:
        # According to the spec, 'Headers' must always be a symlink to the
        # Headers directory inside the currently-selected version of the
        # framework, but sometimes frameworks are broken. Look in 'Versions'
        # for the currently-selected version or pick the latest one.
        trials = ('Headers', 'Versions/Current/Headers',
                  self._get_framework_latest_version(path))
        for each in trials:
            trial = path / each
            if trial.is_dir():
                return trial.as_posix()
        return None

    def log_info(self) -> str:
        return self.framework_path or ''
