# Copyright 2012-2020 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

"""Representations specific to the arm family of compilers."""

import os
import typing as T

from ... import mesonlib
from ...linkers import ArmClangDynamicLinker
from ...mesonlib import OptionKey
from ..compilers import clike_debug_args
from .clang import clang_color_args

if T.TYPE_CHECKING:
    from ...environment import Environment
    from ...compilers.compilers import Compiler
else:
    # This is a bit clever, for mypy we pretend that these mixins descend from
    # Compiler, so we get all of the methods and attributes defined for us, but
    # for runtime we make them descend from object (which all classes normally
    # do). This gives up DRYer type checking, with no runtime impact
    Compiler = object

arm_buildtype_args = {
    'plain': [],
    'debug': [],
    'debugoptimized': [],
    'release': [],
    'minsize': [],
    'custom': [],
}  # type: T.Dict[str, T.List[str]]

arm_optimization_args = {
    'plain': [],
    '0': ['-O0'],
    'g': ['-g'],
    '1': ['-O1'],
    '2': [], # Compiler defaults to -O2
    '3': ['-O3', '-Otime'],
    's': ['-O3'], # Compiler defaults to -Ospace
}  # type: T.Dict[str, T.List[str]]

armclang_buildtype_args = {
    'plain': [],
    'debug': [],
    'debugoptimized': [],
    'release': [],
    'minsize': [],
    'custom': [],
}  # type: T.Dict[str, T.List[str]]

armclang_optimization_args = {
    'plain': [],
    '0': [], # Compiler defaults to -O0
    'g': ['-g'],
    '1': ['-O1'],
    '2': ['-O2'],
    '3': ['-O3'],
    's': ['-Oz']
}  # type: T.Dict[str, T.List[str]]


class ArmCompiler(Compiler):

    """Functionality that is common to all ARM family compilers."""

    id = 'arm'

    def __init__(self) -> None:
        if not self.is_cross:
            raise mesonlib.EnvironmentException('armcc supports only cross-compilation.')
        default_warn_args = []  # type: T.List[str]
        self.warn_args = {'0': [],
                          '1': default_warn_args,
                          '2': default_warn_args + [],
                          '3': default_warn_args + [],
                          'everything': default_warn_args + []}  # type: T.Dict[str, T.List[str]]
        # Assembly
        self.can_compile_suffixes.add('s')
        self.can_compile_suffixes.add('sx')

    def get_pic_args(self) -> T.List[str]:
        # FIXME: Add /ropi, /rwpi, /fpic etc. qualifiers to --apcs
        return []

    def get_buildtype_args(self, buildtype: str) -> T.List[str]:
        return arm_buildtype_args[buildtype]

    # Override CCompiler.get_always_args
    def get_always_args(self) -> T.List[str]:
        return []

    def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
        return ['--depend_target', outtarget, '--depend', outfile, '--depend_single_line']

    def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]:
        # FIXME: Add required arguments
        # NOTE from armcc user guide:
        # "Support for Precompiled Header (PCH) files is deprecated from ARM Compiler 5.05
        # onwards on all platforms. Note that ARM Compiler on Windows 8 never supported
        # PCH files."
        return []

    def get_pch_suffix(self) -> str:
        # NOTE from armcc user guide:
        # "Support for Precompiled Header (PCH) files is deprecated from ARM Compiler 5.05
        # onwards on all platforms. Note that ARM Compiler on Windows 8 never supported
        # PCH files."
        return 'pch'

    def thread_flags(self, env: 'Environment') -> T.List[str]:
        return []

    def get_coverage_args(self) -> T.List[str]:
        return []

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

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

    def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], build_dir: str) -> T.List[str]:
        for idx, i in enumerate(parameter_list):
            if i[:2] == '-I' or i[:2] == '-L':
                parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:]))

        return parameter_list


class ArmclangCompiler(Compiler):
    '''
    This is the Keil armclang.
    '''

    id = 'armclang'

    def __init__(self) -> None:
        if not self.is_cross:
            raise mesonlib.EnvironmentException('armclang supports only cross-compilation.')
        # Check whether 'armlink' is available in path
        if not isinstance(self.linker, ArmClangDynamicLinker):
            raise mesonlib.EnvironmentException(f'Unsupported Linker {self.linker.exelist}, must be armlink')
        if not mesonlib.version_compare(self.version, '==' + self.linker.version):
            raise mesonlib.EnvironmentException('armlink version does not match with compiler version')
        self.base_options = {
            OptionKey(o) for o in
            ['b_pch', 'b_lto', 'b_pgo', 'b_sanitize', 'b_coverage',
             'b_ndebug', 'b_staticpic', 'b_colorout']}
        # Assembly
        self.can_compile_suffixes.add('s')
        self.can_compile_suffixes.add('sx')

    def get_pic_args(self) -> T.List[str]:
        # PIC support is not enabled by default for ARM,
        # if users want to use it, they need to add the required arguments explicitly
        return []

    def get_colorout_args(self, colortype: str) -> T.List[str]:
        return clang_color_args[colortype][:]

    def get_buildtype_args(self, buildtype: str) -> T.List[str]:
        return armclang_buildtype_args[buildtype]

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

    def get_pch_use_args(self, pch_dir: str, header: str) -> T.List[str]:
        # Workaround for Clang bug http://llvm.org/bugs/show_bug.cgi?id=15136
        # This flag is internal to Clang (or at least not documented on the man page)
        # so it might change semantics at any time.
        return ['-include-pch', os.path.join(pch_dir, self.get_pch_name(header))]

    def get_dependency_gen_args(self, outtarget: str, outfile: str) -> T.List[str]:
        return ['-MD', '-MT', outtarget, '-MF', outfile]

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

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

    def compute_parameters_with_absolute_paths(self, parameter_list: T.List[str], build_dir: str) -> T.List[str]:
        for idx, i in enumerate(parameter_list):
            if i[:2] == '-I' or i[:2] == '-L':
                parameter_list[idx] = i[:2] + os.path.normpath(os.path.join(build_dir, i[2:]))

        return parameter_list
