# SPDX-License-Identifier: Apache-2.0
# Copyright 2013-2014 The Meson development team

from __future__ import annotations

import re
import typing as T

from . import coredata
from . import mesonlib
from . import mparser
from . import mlog
from .interpreterbase import FeatureNew, FeatureDeprecated, typed_pos_args, typed_kwargs, ContainerTypeInfo, KwargInfo
from .interpreter.type_checking import NoneType, in_set_validator

if T.TYPE_CHECKING:
    from .interpreterbase import TYPE_var, TYPE_kwargs
    from .interpreterbase import SubProject
    from typing_extensions import TypedDict, Literal

    _DEPRECATED_ARGS = T.Union[bool, str, T.Dict[str, str], T.List[str]]

    FuncOptionArgs = TypedDict('FuncOptionArgs', {
        'type': str,
        'description': str,
        'yield': bool,
        'choices': T.Optional[T.List[str]],
        'value': object,
        'min': T.Optional[int],
        'max': T.Optional[int],
        'deprecated': _DEPRECATED_ARGS,
        })

    class StringArgs(TypedDict):
        value: str

    class BooleanArgs(TypedDict):
        value: bool

    class ComboArgs(TypedDict):
        value: str
        choices: T.List[str]

    class IntegerArgs(TypedDict):
        value: int
        min: T.Optional[int]
        max: T.Optional[int]

    class StringArrayArgs(TypedDict):
        value: T.Optional[T.Union[str, T.List[str]]]
        choices: T.List[str]

    class FeatureArgs(TypedDict):
        value: Literal['enabled', 'disabled', 'auto']
        choices: T.List[str]


class OptionException(mesonlib.MesonException):
    pass


optname_regex = re.compile('[^a-zA-Z0-9_-]')


class OptionInterpreter:
    def __init__(self, subproject: 'SubProject') -> None:
        self.options: 'coredata.MutableKeyedOptionDictType' = {}
        self.subproject = subproject
        self.option_types: T.Dict[str, T.Callable[..., coredata.UserOption]] = {
            'string': self.string_parser,
            'boolean': self.boolean_parser,
            'combo': self.combo_parser,
            'integer': self.integer_parser,
            'array': self.string_array_parser,
            'feature': self.feature_parser,
        }

    def process(self, option_file: str) -> None:
        try:
            with open(option_file, encoding='utf-8') as f:
                ast = mparser.Parser(f.read(), option_file).parse()
        except mesonlib.MesonException as me:
            me.file = option_file
            raise me
        if not isinstance(ast, mparser.CodeBlockNode):
            e = OptionException('Option file is malformed.')
            e.lineno = ast.lineno()
            e.file = option_file
            raise e
        for cur in ast.lines:
            try:
                self.current_node = cur
                self.evaluate_statement(cur)
            except mesonlib.MesonException as e:
                e.lineno = cur.lineno
                e.colno = cur.colno
                e.file = option_file
                raise e
            except Exception as e:
                raise mesonlib.MesonException(
                    str(e), lineno=cur.lineno, colno=cur.colno, file=option_file)

    def reduce_single(self, arg: T.Union[str, mparser.BaseNode]) -> 'TYPE_var':
        if isinstance(arg, str):
            return arg
        if isinstance(arg, mparser.ParenthesizedNode):
            return self.reduce_single(arg.inner)
        elif isinstance(arg, (mparser.BaseStringNode, mparser.BooleanNode,
                              mparser.NumberNode)):
            return arg.value
        elif isinstance(arg, mparser.ArrayNode):
            return [self.reduce_single(curarg) for curarg in arg.args.arguments]
        elif isinstance(arg, mparser.DictNode):
            d = {}
            for k, v in arg.args.kwargs.items():
                if not isinstance(k, mparser.BaseStringNode):
                    raise OptionException('Dictionary keys must be a string literal')
                d[k.value] = self.reduce_single(v)
            return d
        elif isinstance(arg, mparser.UMinusNode):
            res = self.reduce_single(arg.value)
            if not isinstance(res, (int, float)):
                raise OptionException('Token after "-" is not a number')
            FeatureNew.single_use('negative numbers in meson_options.txt', '0.54.1', self.subproject)
            return -res
        elif isinstance(arg, mparser.NotNode):
            res = self.reduce_single(arg.value)
            if not isinstance(res, bool):
                raise OptionException('Token after "not" is not a a boolean')
            FeatureNew.single_use('negation ("not") in meson_options.txt', '0.54.1', self.subproject)
            return not res
        elif isinstance(arg, mparser.ArithmeticNode):
            l = self.reduce_single(arg.left)
            r = self.reduce_single(arg.right)
            if not (arg.operation == 'add' and isinstance(l, str) and isinstance(r, str)):
                raise OptionException('Only string concatenation with the "+" operator is allowed')
            FeatureNew.single_use('string concatenation in meson_options.txt', '0.55.0', self.subproject)
            return l + r
        else:
            raise OptionException('Arguments may only be string, int, bool, or array of those.')

    def reduce_arguments(self, args: mparser.ArgumentNode) -> T.Tuple['TYPE_var', 'TYPE_kwargs']:
        if args.incorrect_order():
            raise OptionException('All keyword arguments must be after positional arguments.')
        reduced_pos = [self.reduce_single(arg) for arg in args.arguments]
        reduced_kw = {}
        for key in args.kwargs.keys():
            if not isinstance(key, mparser.IdNode):
                raise OptionException('Keyword argument name is not a string.')
            a = args.kwargs[key]
            reduced_kw[key.value] = self.reduce_single(a)
        return reduced_pos, reduced_kw

    def evaluate_statement(self, node: mparser.BaseNode) -> None:
        if not isinstance(node, mparser.FunctionNode):
            raise OptionException('Option file may only contain option definitions')
        func_name = node.func_name.value
        if func_name != 'option':
            raise OptionException('Only calls to option() are allowed in option files.')
        (posargs, kwargs) = self.reduce_arguments(node.args)
        self.func_option(posargs, kwargs)

    @typed_kwargs(
        'option',
        KwargInfo(
            'type',
            str,
            required=True,
            validator=in_set_validator({'string', 'boolean', 'integer', 'combo', 'array', 'feature'})
        ),
        KwargInfo('description', str, default=''),
        KwargInfo(
            'deprecated',
            (bool, str, ContainerTypeInfo(dict, str), ContainerTypeInfo(list, str)),
            default=False,
            since='0.60.0',
            since_values={str: '0.63.0'},
        ),
        KwargInfo('yield', bool, default=coredata.DEFAULT_YIELDING, since='0.45.0'),
        allow_unknown=True,
    )
    @typed_pos_args('option', str)
    def func_option(self, args: T.Tuple[str], kwargs: 'FuncOptionArgs') -> None:
        opt_name = args[0]
        if optname_regex.search(opt_name) is not None:
            raise OptionException('Option names can only contain letters, numbers or dashes.')
        key = mesonlib.OptionKey.from_string(opt_name).evolve(subproject=self.subproject)
        if not key.is_project():
            raise OptionException('Option name %s is reserved.' % opt_name)

        opt_type = kwargs['type']
        parser = self.option_types[opt_type]
        description = kwargs['description'] or opt_name

        # Drop the arguments we've already consumed
        n_kwargs = {k: v for k, v in kwargs.items()
                    if k not in {'type', 'description', 'deprecated', 'yield'}}

        opt = parser(description, (kwargs['yield'], kwargs['deprecated']), n_kwargs)
        if key in self.options:
            mlog.deprecation(f'Option {opt_name} already exists.')
        self.options[key] = opt

    @typed_kwargs(
        'string option',
        KwargInfo('value', str, default=''),
    )
    def string_parser(self, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: StringArgs) -> coredata.UserOption:
        return coredata.UserStringOption(description, kwargs['value'], *args)

    @typed_kwargs(
        'boolean option',
        KwargInfo(
            'value',
            (bool, str),
            default=True,
            validator=lambda x: None if isinstance(x, bool) or x in {'true', 'false'} else 'boolean options must have boolean values',
            deprecated_values={str: ('1.1.0', 'use a boolean, not a string')},
        ),
    )
    def boolean_parser(self, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: BooleanArgs) -> coredata.UserOption:
        return coredata.UserBooleanOption(description, kwargs['value'], *args)

    @typed_kwargs(
        'combo option',
        KwargInfo('value', (str, NoneType)),
        KwargInfo('choices', ContainerTypeInfo(list, str, allow_empty=False), required=True),
    )
    def combo_parser(self, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: ComboArgs) -> coredata.UserOption:
        choices = kwargs['choices']
        value = kwargs['value']
        if value is None:
            value = kwargs['choices'][0]
        return coredata.UserComboOption(description, choices, value, *args)

    @typed_kwargs(
        'integer option',
        KwargInfo(
            'value',
            (int, str),
            default=True,
            deprecated_values={str: ('1.1.0', 'use an integer, not a string')},
            convertor=int,
        ),
        KwargInfo('min', (int, NoneType)),
        KwargInfo('max', (int, NoneType)),
    )
    def integer_parser(self, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: IntegerArgs) -> coredata.UserOption:
        value = kwargs['value']
        inttuple = (kwargs['min'], kwargs['max'], value)
        return coredata.UserIntegerOption(description, inttuple, *args)

    @typed_kwargs(
        'string array option',
        KwargInfo('value', (ContainerTypeInfo(list, str), str, NoneType)),
        KwargInfo('choices', ContainerTypeInfo(list, str), default=[]),
    )
    def string_array_parser(self, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: StringArrayArgs) -> coredata.UserOption:
        choices = kwargs['choices']
        value = kwargs['value'] if kwargs['value'] is not None else choices
        if isinstance(value, str):
            if value.startswith('['):
                FeatureDeprecated('String value for array option', '1.3.0').use(self.subproject)
            else:
                raise mesonlib.MesonException('Value does not define an array: ' + value)
        return coredata.UserArrayOption(description, value,
                                        choices=choices,
                                        yielding=args[0],
                                        deprecated=args[1])

    @typed_kwargs(
        'feature option',
        KwargInfo('value', str, default='auto', validator=in_set_validator({'auto', 'enabled', 'disabled'})),
    )
    def feature_parser(self, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: FeatureArgs) -> coredata.UserOption:
        return coredata.UserFeatureOption(description, kwargs['value'], *args)
