# Copyright 2012-2017 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 __future__ import annotations

import os.path
import typing as T

from .. import mlog
from ..mesonlib import EnvironmentException, version_compare, OptionKey

from .compilers import Compiler, LibType

if T.TYPE_CHECKING:
    from ..envconfig import MachineInfo
    from ..environment import Environment
    from ..mesonlib import MachineChoice

class ValaCompiler(Compiler):

    language = 'vala'
    id = 'valac'

    def __init__(self, exelist: T.List[str], version: str, for_machine: MachineChoice,
                 is_cross: bool, info: 'MachineInfo'):
        super().__init__(exelist, version, for_machine, info, is_cross=is_cross)
        self.version = version
        self.base_options = {OptionKey('b_colorout')}

    def needs_static_linker(self) -> bool:
        return False # Because compiles into C.

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

    def get_debug_args(self, is_debug: bool) -> T.List[str]:
        return ['--debug'] if is_debug else []

    def get_output_args(self, target: str) -> T.List[str]:
        return [] # Because compiles into C.

    def get_compile_only_args(self) -> T.List[str]:
        return [] # Because compiles into C.

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

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

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

    def get_always_args(self) -> T.List[str]:
        return ['-C']

    def get_warn_args(self, warning_level: str) -> T.List[str]:
        return []

    def get_no_warn_args(self) -> T.List[str]:
        return ['--disable-warnings']

    def get_werror_args(self) -> T.List[str]:
        return ['--fatal-warnings']

    def get_colorout_args(self, colortype: str) -> T.List[str]:
        if version_compare(self.version, '>=0.37.1'):
            return ['--color=' + colortype]
        return []

    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[:9] == '--girdir=':
                parameter_list[idx] = i[:9] + os.path.normpath(os.path.join(build_dir, i[9:]))
            if i[:10] == '--vapidir=':
                parameter_list[idx] = i[:10] + os.path.normpath(os.path.join(build_dir, i[10:]))
            if i[:13] == '--includedir=':
                parameter_list[idx] = i[:13] + os.path.normpath(os.path.join(build_dir, i[13:]))
            if i[:14] == '--metadatadir=':
                parameter_list[idx] = i[:14] + os.path.normpath(os.path.join(build_dir, i[14:]))

        return parameter_list

    def sanity_check(self, work_dir: str, environment: 'Environment') -> None:
        code = 'class MesonSanityCheck : Object { }'
        extra_flags: T.List[str] = []
        extra_flags += environment.coredata.get_external_args(self.for_machine, self.language)
        if self.is_cross:
            extra_flags += self.get_compile_only_args()
        else:
            extra_flags += environment.coredata.get_external_link_args(self.for_machine, self.language)
        with self.cached_compile(code, environment.coredata, extra_args=extra_flags, mode='compile') as p:
            if p.returncode != 0:
                msg = f'Vala compiler {self.name_string()!r} can not compile programs'
                raise EnvironmentException(msg)

    def get_buildtype_args(self, buildtype: str) -> T.List[str]:
        if buildtype in {'debug', 'debugoptimized', 'minsize'}:
            return ['--debug']
        return []

    def find_library(self, libname: str, env: 'Environment', extra_dirs: T.List[str],
                     libtype: LibType = LibType.PREFER_SHARED) -> T.Optional[T.List[str]]:
        if extra_dirs and isinstance(extra_dirs, str):
            extra_dirs = [extra_dirs]
        # Valac always looks in the default vapi dir, so only search there if
        # no extra dirs are specified.
        if not extra_dirs:
            code = 'class MesonFindLibrary : Object { }'
            args: T.List[str] = []
            args += env.coredata.get_external_args(self.for_machine, self.language)
            vapi_args = ['--pkg', libname]
            args += vapi_args
            with self.cached_compile(code, env.coredata, extra_args=args, mode='compile') as p:
                if p.returncode == 0:
                    return vapi_args
        # Not found? Try to find the vapi file itself.
        for d in extra_dirs:
            vapi = os.path.join(d, libname + '.vapi')
            if os.path.isfile(vapi):
                return [vapi]
        mlog.debug(f'Searched {extra_dirs!r} and {libname!r} wasn\'t found')
        return None

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

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