# Copyright 2019 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.

"""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

if T.TYPE_CHECKING:
    from ...arglist import CompilerArgs
    from ...dependencies import Dependency
    from ...environment import Environment

# 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
    """

    BUILD_ARGS = {
        'plain': [],
        'debug': ["-g", "-traceback"],
        'debugoptimized': ["-g", "-traceback"],
        'release': [],
        'minsize': [],
        'custom': [],
    }  # type: T.Dict[str, T.List[str]]

    OPTIM_ARGS = {
        '0': ['-O0'],
        'g': ['-O0'],
        '1': ['-O1'],
        '2': ['-O2'],
        '3': ['-O3'],
        's': ['-Os'],
    }

    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.id = 'intel'
        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, header_name: str) -> str:
        return os.path.basename(header_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_buildtype_args(self, buildtype: str) -> T.List[str]:
        return self.BUILD_ARGS[buildtype]

    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."""

    BUILD_ARGS = {
        'plain': [],
        'debug': ["/Zi", "/traceback"],
        'debugoptimized': ["/Zi", "/traceback"],
        'release': [],
        'minsize': [],
        'custom': [],
    }  # type: T.Dict[str, T.List[str]]

    OPTIM_ARGS = {
        '0': ['/Od'],
        'g': ['/Od'],
        '1': ['/O1'],
        '2': ['/O2'],
        '3': ['/O3'],
        's': ['/Os'],
    }

    def __init__(self, target: str) -> None:
        super().__init__(target)
        self.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]:
        # Avoid circular dependencies....
        from ...environment import search_version

        # 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, *_ = 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_buildtype_args(self, buildtype: str) -> T.List[str]:
        return self.BUILD_ARGS[buildtype]

    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)