# 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 pathlib import Path
from .traceparser import CMakeTraceParser
from ..envconfig import CMakeSkipCompilerTest
from ..mesonlib import MachineChoice
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

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)
