# Copyright 2020 The Meson development team

# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at

#     http://www.apache.org/licenses/LICENSE-2.0

# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from __future__ import annotations

from pathlib import Path
from .traceparser import CMakeTraceParser
from ..envconfig import CMakeSkipCompilerTest
from ..compilers import VisualStudioLikeCompiler
from .common import language_map, cmake_get_generator_args
from .. import mlog

import shutil
import typing as T
from enum import Enum
from textwrap import dedent

if T.TYPE_CHECKING:
    from .executor import CMakeExecutor
    from ..environment import Environment
    from ..compilers import Compiler
    from ..mesonlib import MachineChoice

class CMakeExecScope(Enum):
    SUBPROJECT = 'subproject'
    DEPENDENCY = 'dependency'

class CMakeToolchain:
    def __init__(self, cmakebin: 'CMakeExecutor', env: 'Environment', for_machine: MachineChoice, exec_scope: CMakeExecScope, build_dir: Path, preload_file: T.Optional[Path] = None) -> None:
        self.env = env
        self.cmakebin = cmakebin
        self.for_machine = for_machine
        self.exec_scope = exec_scope
        self.preload_file = preload_file
        self.build_dir = build_dir
        self.build_dir = self.build_dir.resolve()
        self.toolchain_file = build_dir / 'CMakeMesonToolchainFile.cmake'
        self.cmcache_file = build_dir / 'CMakeCache.txt'
        self.minfo = self.env.machines[self.for_machine]
        self.properties = self.env.properties[self.for_machine]
        self.compilers = self.env.coredata.compilers[self.for_machine]
        self.cmakevars = self.env.cmakevars[self.for_machine]
        self.cmakestate = self.env.coredata.cmake_cache[self.for_machine]

        self.variables = self.get_defaults()
        self.variables.update(self.cmakevars.get_variables())

        # Determine whether CMake the compiler test should be skipped
        skip_status = self.properties.get_cmake_skip_compiler_test()
        self.skip_check = skip_status == CMakeSkipCompilerTest.ALWAYS
        if skip_status == CMakeSkipCompilerTest.DEP_ONLY and self.exec_scope == CMakeExecScope.DEPENDENCY:
            self.skip_check = True
        if not self.properties.get_cmake_defaults():
            self.skip_check = False

        assert self.toolchain_file.is_absolute()

    def write(self) -> Path:
        if not self.toolchain_file.parent.exists():
            self.toolchain_file.parent.mkdir(parents=True)
        self.toolchain_file.write_text(self.generate(), encoding='utf-8')
        self.cmcache_file.write_text(self.generate_cache(), encoding='utf-8')
        mlog.cmd_ci_include(self.toolchain_file.as_posix())
        return self.toolchain_file

    def get_cmake_args(self) -> T.List[str]:
        args = ['-DCMAKE_TOOLCHAIN_FILE=' + self.toolchain_file.as_posix()]
        if self.preload_file is not None:
            args += ['-DMESON_PRELOAD_FILE=' + self.preload_file.as_posix()]
        return args

    @staticmethod
    def _print_vars(vars: T.Dict[str, T.List[str]]) -> str:
        res = ''
        for key, value in vars.items():
            res += 'set(' + key
            for i in value:
                res += f' "{i}"'
            res += ')\n'
        return res

    def generate(self) -> str:
        res = dedent('''\
            ######################################
            ###  AUTOMATICALLY GENERATED FILE  ###
            ######################################

            # This file was generated from the configuration in the
            # relevant meson machine file. See the meson documentation
            # https://mesonbuild.com/Machine-files.html for more information

            if(DEFINED MESON_PRELOAD_FILE)
                include("${MESON_PRELOAD_FILE}")
            endif()

        ''')

        # Escape all \ in the values
        for key, value in self.variables.items():
            self.variables[key] = [x.replace('\\', '/') for x in value]

        # Set compiler
        if self.skip_check:
            self.update_cmake_compiler_state()
            res += '# CMake compiler state variables\n'
            for lang, vars in self.cmakestate:
                res += f'# -- Variables for language {lang}\n'
                res += self._print_vars(vars)
                res += '\n'
            res += '\n'

        # Set variables from the current machine config
        res += '# Variables from meson\n'
        res += self._print_vars(self.variables)
        res += '\n'

        # Add the user provided toolchain file
        user_file = self.properties.get_cmake_toolchain_file()
        if user_file is not None:
            res += dedent('''
                # Load the CMake toolchain file specified by the user
                include("{}")

            '''.format(user_file.as_posix()))

        return res

    def generate_cache(self) -> str:
        if not self.skip_check:
            return ''

        res = ''
        for name, v in self.cmakestate.cmake_cache.items():
            res += f'{name}:{v.type}={";".join(v.value)}\n'
        return res

    def get_defaults(self) -> T.Dict[str, T.List[str]]:
        defaults = {}  # type: T.Dict[str, T.List[str]]

        # Do nothing if the user does not want automatic defaults
        if not self.properties.get_cmake_defaults():
            return defaults

        # Best effort to map the meson system name to CMAKE_SYSTEM_NAME, which
        # is not trivial since CMake lacks a list of all supported
        # CMAKE_SYSTEM_NAME values.
        SYSTEM_MAP = {
            'android': 'Android',
            'linux': 'Linux',
            'windows': 'Windows',
            'freebsd': 'FreeBSD',
            'darwin': 'Darwin',
        }  # type: T.Dict[str, str]

        # Only set these in a cross build. Otherwise CMake will trip up in native
        # builds and thing they are cross (which causes TRY_RUN() to break)
        if self.env.is_cross_build(when_building_for=self.for_machine):
            defaults['CMAKE_SYSTEM_NAME'] = [SYSTEM_MAP.get(self.minfo.system, self.minfo.system)]
            defaults['CMAKE_SYSTEM_PROCESSOR'] = [self.minfo.cpu_family]

        defaults['CMAKE_SIZEOF_VOID_P'] = ['8' if self.minfo.is_64_bit else '4']

        sys_root = self.properties.get_sys_root()
        if sys_root:
            defaults['CMAKE_SYSROOT'] = [sys_root]

        def make_abs(exe: str) -> str:
            if Path(exe).is_absolute():
                return exe

            p = shutil.which(exe)
            if p is None:
                return exe
            return p

        # Set the compiler variables
        for lang, comp_obj in self.compilers.items():
            prefix = 'CMAKE_{}_'.format(language_map.get(lang, lang.upper()))

            exe_list = comp_obj.get_exelist()
            if not exe_list:
                continue

            if len(exe_list) >= 2 and not self.is_cmdline_option(comp_obj, exe_list[1]):
                defaults[prefix + 'COMPILER_LAUNCHER'] = [make_abs(exe_list[0])]
                exe_list = exe_list[1:]

            exe_list[0] = make_abs(exe_list[0])
            defaults[prefix + 'COMPILER'] = exe_list
            if comp_obj.get_id() == 'clang-cl':
                defaults['CMAKE_LINKER'] = comp_obj.get_linker_exelist()

        return defaults

    @staticmethod
    def is_cmdline_option(compiler: 'Compiler', arg: str) -> bool:
        if isinstance(compiler, VisualStudioLikeCompiler):
            return arg.startswith('/')
        else:
            return arg.startswith('-')

    def update_cmake_compiler_state(self) -> None:
        # Check if all variables are already cached
        if self.cmakestate.languages.issuperset(self.compilers.keys()):
            return

        # Generate the CMakeLists.txt
        mlog.debug('CMake Toolchain: Calling CMake once to generate the compiler state')
        languages = list(self.compilers.keys())
        lang_ids = [language_map.get(x, x.upper()) for x in languages]
        cmake_content = dedent(f'''
            cmake_minimum_required(VERSION 3.7)
            project(CompInfo {' '.join(lang_ids)})
        ''')

        build_dir = Path(self.env.scratch_dir) / '__CMake_compiler_info__'
        build_dir.mkdir(parents=True, exist_ok=True)
        cmake_file = build_dir / 'CMakeLists.txt'
        cmake_file.write_text(cmake_content, encoding='utf-8')

        # Generate the temporary toolchain file
        temp_toolchain_file = build_dir / 'CMakeMesonTempToolchainFile.cmake'
        temp_toolchain_file.write_text(CMakeToolchain._print_vars(self.variables), encoding='utf-8')

        # Configure
        trace = CMakeTraceParser(self.cmakebin.version(), build_dir, self.env)
        self.cmakebin.set_exec_mode(print_cmout=False, always_capture_stderr=trace.requires_stderr())
        cmake_args = []
        cmake_args += trace.trace_args()
        cmake_args += cmake_get_generator_args(self.env)
        cmake_args += [f'-DCMAKE_TOOLCHAIN_FILE={temp_toolchain_file.as_posix()}', '.']
        rc, _, raw_trace = self.cmakebin.call(cmake_args, build_dir=build_dir, disable_cache=True)

        if rc != 0:
            mlog.warning('CMake Toolchain: Failed to determine CMake compilers state')
            return

        # Parse output
        trace.parse(raw_trace)
        self.cmakestate.cmake_cache = {**trace.cache}

        vars_by_file = {k.name: v for (k, v) in trace.vars_by_file.items()}

        for lang in languages:
            lang_cmake = language_map.get(lang, lang.upper())
            file_name = f'CMake{lang_cmake}Compiler.cmake'
            vars = vars_by_file.setdefault(file_name, {})
            vars[f'CMAKE_{lang_cmake}_COMPILER_FORCED'] = ['1']
            self.cmakestate.update(lang, vars)
