# SPDX-License-Identifier: Apache-2.0
# Copyright 2019 The meson development team

from __future__ import annotations

"""Abstractions for the Intel Compiler families.

Intel provides both a posix/gcc-like compiler (ICC) for MacOS and Linux,
with Meson mixin IntelGnuLikeCompiler.
For Windows, the Intel msvc-like compiler (ICL) Meson mixin
is IntelVisualStudioLikeCompiler.
"""

import os
import typing as T

from ... import mesonlib
from ..compilers import CompileCheckMode
from .gnu import GnuLikeCompiler
from .visualstudio import VisualStudioLikeCompiler

# XXX: avoid circular dependencies
# TODO: this belongs in a posix compiler class
# NOTE: the default Intel optimization is -O2, unlike GNU which defaults to -O0.
# this can be surprising, particularly for debug builds, so we specify the
# default as -O0.
# https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-o
# https://software.intel.com/en-us/cpp-compiler-developer-guide-and-reference-g
# https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-o
# https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-g
# https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-traceback
# https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html


class IntelGnuLikeCompiler(GnuLikeCompiler):
    """
    Tested on linux for ICC 14.0.3, 15.0.6, 16.0.4, 17.0.1, 19.0
    debugoptimized: -g -O2
    release: -O3
    minsize: -O2
    """

    DEBUG_ARGS: T.Dict[bool, T.List[str]] = {
        False: [],
        True: ['-g', '-traceback']
    }

    OPTIM_ARGS: T.Dict[str, T.List[str]] = {
        'plain': [],
        '0': ['-O0'],
        'g': ['-O0'],
        '1': ['-O1'],
        '2': ['-O2'],
        '3': ['-O3'],
        's': ['-Os'],
    }
    id = 'intel'

    def __init__(self) -> None:
        super().__init__()
        # As of 19.0.0 ICC doesn't have sanitizer, color, or lto support.
        #
        # It does have IPO, which serves much the same purpose as LOT, but
        # there is an unfortunate rule for using IPO (you can't control the
        # name of the output file) which break assumptions meson makes
        self.base_options = {mesonlib.OptionKey(o) for o in [
            'b_pch', 'b_lundef', 'b_asneeded', 'b_pgo', 'b_coverage',
            'b_ndebug', 'b_staticpic', 'b_pie']}
        self.lang_header = 'none'

    def get_pch_suffix(self) -> str:
        return 'pchi'

    def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]:
        return ['-pch', '-pch_dir', os.path.join(pch_dir), '-x',
                self.lang_header, '-include', header, '-x', 'none']

    def get_pch_name(self, name: str) -> str:
        return os.path.basename(name) + '.' + self.get_pch_suffix()

    def openmp_flags(self) -> T.List[str]:
        if mesonlib.version_compare(self.version, '>=15.0.0'):
            return ['-qopenmp']
        else:
            return ['-openmp']

    def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
        extra_args = [
            '-diag-error', '10006',  # ignoring unknown option
            '-diag-error', '10148',  # Option not supported
            '-diag-error', '10155',  # ignoring argument required
            '-diag-error', '10156',  # ignoring not argument allowed
            '-diag-error', '10157',  # Ignoring argument of the wrong type
            '-diag-error', '10158',  # Argument must be separate. Can be hit by trying an option like -foo-bar=foo when -foo=bar is a valid option but -foo-bar isn't
        ]
        return super().get_compiler_check_args(mode) + extra_args

    def get_profile_generate_args(self) -> T.List[str]:
        return ['-prof-gen=threadsafe']

    def get_profile_use_args(self) -> T.List[str]:
        return ['-prof-use']

    def get_debug_args(self, is_debug: bool) -> T.List[str]:
        return self.DEBUG_ARGS[is_debug]

    def get_optimization_args(self, optimization_level: str) -> T.List[str]:
        return self.OPTIM_ARGS[optimization_level]

    def get_has_func_attribute_extra_args(self, name: str) -> T.List[str]:
        return ['-diag-error', '1292']


class IntelVisualStudioLikeCompiler(VisualStudioLikeCompiler):

    """Abstractions for ICL, the Intel compiler on Windows."""

    DEBUG_ARGS: T.Dict[bool, T.List[str]] = {
        False: [],
        True: ['/Zi', '/traceback']
    }

    OPTIM_ARGS: T.Dict[str, T.List[str]] = {
        'plain': [],
        '0': ['/Od'],
        'g': ['/Od'],
        '1': ['/O1'],
        '2': ['/O2'],
        '3': ['/O3'],
        's': ['/Os'],
    }

    id = 'intel-cl'

    def get_compiler_check_args(self, mode: CompileCheckMode) -> T.List[str]:
        args = super().get_compiler_check_args(mode)
        if mode is not CompileCheckMode.LINK:
            args.extend([
                '/Qdiag-error:10006',  # ignoring unknown option
                '/Qdiag-error:10148',  # Option not supported
                '/Qdiag-error:10155',  # ignoring argument required
                '/Qdiag-error:10156',  # ignoring not argument allowed
                '/Qdiag-error:10157',  # Ignoring argument of the wrong type
                '/Qdiag-error:10158',  # Argument must be separate. Can be hit by trying an option like -foo-bar=foo when -foo=bar is a valid option but -foo-bar isn't
            ])
        return args

    def get_toolset_version(self) -> T.Optional[str]:
        # ICL provides a cl.exe that returns the version of MSVC it tries to
        # emulate, so we'll get the version from that and pass it to the same
        # function the real MSVC uses to calculate the toolset version.
        _, _, err = mesonlib.Popen_safe(['cl.exe'])
        v1, v2, *_ = mesonlib.search_version(err).split('.')
        version = int(v1 + v2)
        return self._calculate_toolset_version(version)

    def openmp_flags(self) -> T.List[str]:
        return ['/Qopenmp']

    def get_debug_args(self, is_debug: bool) -> T.List[str]:
        return self.DEBUG_ARGS[is_debug]

    def get_optimization_args(self, optimization_level: str) -> T.List[str]:
        return self.OPTIM_ARGS[optimization_level]

    def get_pch_base_name(self, header: str) -> str:
        return os.path.basename(header)
