# SPDX-License-Identifier: Apache-2.0
# Copyright 2021 The Meson development team
from __future__ import annotations

from .common import cmake_is_debug
from .. import mlog
from ..mesonlib import Version

from pathlib import Path
import re
import typing as T

if T.TYPE_CHECKING:
    from .traceparser import CMakeTraceParser
    from ..environment import Environment
    from ..compilers import Compiler
    from ..dependencies import MissingCompiler

# Small duplication of ExtraFramework to parse full
# framework paths as exposed by CMake
def _get_framework_latest_version(path: Path) -> str:
    versions: 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(path: Path) -> T.Optional[str]:
    trials = ('Headers', 'Versions/Current/Headers', _get_framework_latest_version(path))
    for each in trials:
        trial = path / each
        if trial.is_dir():
            return trial.as_posix()
    return None

class ResolvedTarget:
    def __init__(self) -> None:
        self.include_directories: T.List[str] = []
        self.link_flags:          T.List[str] = []
        self.public_compile_opts: T.List[str] = []
        self.libraries:           T.List[str] = []

def resolve_cmake_trace_targets(target_name: str,
                                trace: 'CMakeTraceParser',
                                env: 'Environment',
                                *,
                                clib_compiler: T.Union['MissingCompiler', 'Compiler'] = None,
                                not_found_warning: T.Callable[[str], None] = lambda x: None) -> ResolvedTarget:
    res = ResolvedTarget()
    targets = [target_name]

    # recognise arguments we should pass directly to the linker
    reg_is_lib = re.compile(r'^(-l[a-zA-Z0-9_]+|-l?pthread)$')
    reg_is_maybe_bare_lib = re.compile(r'^[a-zA-Z0-9_]+$')

    is_debug = cmake_is_debug(env)

    processed_targets: T.List[str] = []
    while len(targets) > 0:
        curr = targets.pop(0)

        # Skip already processed targets
        if curr in processed_targets:
            continue

        if curr not in trace.targets:
            curr_path = Path(curr)
            if reg_is_lib.match(curr):
                res.libraries += [curr]
            elif curr_path.is_absolute() and curr_path.exists():
                if any(x.endswith('.framework') for x in curr_path.parts):
                    # Frameworks detected by CMake are passed as absolute paths
                    # Split into -F/path/to/ and -framework name
                    path_to_framework = []
                    # Try to slice off the `Versions/X/name.tbd`
                    for x in curr_path.parts:
                        path_to_framework.append(x)
                        if x.endswith('.framework'):
                            break
                    curr_path = Path(*path_to_framework)
                    framework_path = curr_path.parent
                    framework_name = curr_path.stem
                    res.libraries += [f'-F{framework_path}', '-framework', framework_name]
                else:
                    res.libraries += [curr]
            elif reg_is_maybe_bare_lib.match(curr) and clib_compiler:
                # CMake library dependencies can be passed as bare library names,
                # CMake brute-forces a combination of prefix/suffix combinations to find the
                # right library. Assume any bare argument passed which is not also a CMake
                # target must be a system library we should try to link against.
                flib = clib_compiler.find_library(curr, env, [])
                if flib is not None:
                    res.libraries += flib
                else:
                    not_found_warning(curr)
            else:
                not_found_warning(curr)
            continue

        tgt = trace.targets[curr]
        cfgs = []
        cfg = ''
        mlog.debug(tgt)

        if 'INTERFACE_INCLUDE_DIRECTORIES' in tgt.properties:
            res.include_directories += [x for x in tgt.properties['INTERFACE_INCLUDE_DIRECTORIES'] if x]

        if 'INTERFACE_LINK_OPTIONS' in tgt.properties:
            res.link_flags += [x for x in tgt.properties['INTERFACE_LINK_OPTIONS'] if x]

        if 'INTERFACE_COMPILE_DEFINITIONS' in tgt.properties:
            res.public_compile_opts += ['-D' + re.sub('^-D', '', x) for x in tgt.properties['INTERFACE_COMPILE_DEFINITIONS'] if x]

        if 'INTERFACE_COMPILE_OPTIONS' in tgt.properties:
            res.public_compile_opts += [x for x in tgt.properties['INTERFACE_COMPILE_OPTIONS'] if x]

        if 'IMPORTED_CONFIGURATIONS' in tgt.properties:
            cfgs = [x for x in tgt.properties['IMPORTED_CONFIGURATIONS'] if x]
            cfg = cfgs[0]

        if is_debug:
            if 'DEBUG' in cfgs:
                cfg = 'DEBUG'
            elif 'RELEASE' in cfgs:
                cfg = 'RELEASE'
        else:
            if 'RELEASE' in cfgs:
                cfg = 'RELEASE'

        if f'IMPORTED_IMPLIB_{cfg}' in tgt.properties:
            res.libraries += [x for x in tgt.properties[f'IMPORTED_IMPLIB_{cfg}'] if x]
        elif 'IMPORTED_IMPLIB' in tgt.properties:
            res.libraries += [x for x in tgt.properties['IMPORTED_IMPLIB'] if x]
        elif f'IMPORTED_LOCATION_{cfg}' in tgt.properties:
            res.libraries += [x for x in tgt.properties[f'IMPORTED_LOCATION_{cfg}'] if x]
        elif 'IMPORTED_LOCATION' in tgt.properties:
            res.libraries += [x for x in tgt.properties['IMPORTED_LOCATION'] if x]

        if 'LINK_LIBRARIES' in tgt.properties:
            targets += [x for x in tgt.properties['LINK_LIBRARIES'] if x]
        if 'INTERFACE_LINK_LIBRARIES' in tgt.properties:
            targets += [x for x in tgt.properties['INTERFACE_LINK_LIBRARIES'] if x]

        if f'IMPORTED_LINK_DEPENDENT_LIBRARIES_{cfg}' in tgt.properties:
            targets += [x for x in tgt.properties[f'IMPORTED_LINK_DEPENDENT_LIBRARIES_{cfg}'] if x]
        elif 'IMPORTED_LINK_DEPENDENT_LIBRARIES' in tgt.properties:
            targets += [x for x in tgt.properties['IMPORTED_LINK_DEPENDENT_LIBRARIES'] if x]

        processed_targets += [curr]

    # Do not sort flags here -- this breaks
    # semantics of eg. `-framework CoreAudio`
    # or `-Lpath/to/root -llibrary`
    # see eg. #11113

    return res
