# 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, stringlistify
from .. import mlog
from pathlib import Path
import typing as T

if T.TYPE_CHECKING:
    from ..environment import Environment

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

    def __init__(self, name: str, env: 'Environment', kwargs: T.Dict[str, T.Any], language: T.Optional[str] = None) -> None:
        paths = stringlistify(kwargs.get('paths', []))
        super().__init__(DependencyTypeName('extraframeworks'), env, kwargs, language=language)
        self.name = name
        # 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(self.env)
            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, self.env, [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 ''

    @staticmethod
    def log_tried() -> str:
        return 'framework'
