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