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

import os.path
import typing as T

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

from .compilers import Compiler, LibType

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

class ValaCompiler(Compiler):

    language = 'vala'

    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.id = 'valac'
        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 []
