# SPDX-License-Identifier: Apache-2.0
# Copyright 2016-2017 The Meson development team

from __future__ import annotations

import sysconfig
import typing as T

from .. import mesonlib
from . import ExtensionModule, ModuleInfo
from ..build import (
    BuildTarget, CustomTarget, CustomTargetIndex, ExtractedObjects,
    GeneratedList, SharedModule, StructuredSources, known_shmod_kwargs
)
from ..interpreter.type_checking import SHARED_MOD_KWS
from ..interpreterbase import typed_kwargs, typed_pos_args, noPosargs, noKwargs, permittedKwargs
from ..programs import ExternalProgram

if T.TYPE_CHECKING:
    from . import ModuleState
    from ..interpreter.interpreter import BuildTargetSource
    from ..interpreter.kwargs import SharedModule as SharedModuleKW


_MOD_KWARGS = [k for k in SHARED_MOD_KWS if k.name not in {'name_prefix', 'name_suffix'}]


class Python3Module(ExtensionModule):

    INFO = ModuleInfo('python3', '0.38.0', deprecated='0.48.0')

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.methods.update({
            'extension_module': self.extension_module,
            'find_python': self.find_python,
            'language_version': self.language_version,
            'sysconfig_path': self.sysconfig_path,
        })

    @permittedKwargs(known_shmod_kwargs - {'name_prefix', 'name_suffix'})
    @typed_pos_args('python3.extension_module', str, varargs=(str, mesonlib.File, CustomTarget, CustomTargetIndex, GeneratedList, StructuredSources, ExtractedObjects, BuildTarget))
    @typed_kwargs('python3.extension_module', *_MOD_KWARGS)
    def extension_module(self, state: ModuleState, args: T.Tuple[str, T.List[BuildTargetSource]], kwargs: SharedModuleKW):
        host_system = state.environment.machines.host.system
        if host_system == 'darwin':
            # Default suffix is 'dylib' but Python does not use it for extensions.
            suffix = 'so'
        elif host_system == 'windows':
            # On Windows the extension is pyd for some unexplainable reason.
            suffix = 'pyd'
        else:
            suffix = None
        kwargs['name_prefix'] = ''
        kwargs['name_suffix'] = suffix
        return self.interpreter.build_target(state.current_node, args, kwargs, SharedModule)

    @noPosargs
    @noKwargs
    def find_python(self, state, args, kwargs):
        command = state.environment.lookup_binary_entry(mesonlib.MachineChoice.HOST, 'python3')
        if command is not None:
            py3 = ExternalProgram.from_entry('python3', command)
        else:
            py3 = ExternalProgram('python3', mesonlib.python_command, silent=True)
        return py3

    @noPosargs
    @noKwargs
    def language_version(self, state, args, kwargs):
        return sysconfig.get_python_version()

    @noKwargs
    @typed_pos_args('python3.sysconfig_path', str)
    def sysconfig_path(self, state, args, kwargs):
        path_name = args[0]
        valid_names = sysconfig.get_path_names()
        if path_name not in valid_names:
            raise mesonlib.MesonException(f'{path_name} is not a valid path name {valid_names}.')

        # Get a relative path without a prefix, e.g. lib/python3.6/site-packages
        return sysconfig.get_path(path_name, vars={'base': '', 'platbase': '', 'installed_base': ''})[1:]


def initialize(*args, **kwargs):
    return Python3Module(*args, **kwargs)
