# 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, lib_prefix_warning: bool = True) -> 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 []
