# 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 options
from . import mesonlib
from .options import OptionKey
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 .mesonlib import SubProject
    from typing_extensions import TypedDict, Literal
    from .options import OptionStore

    _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, optionstore: 'OptionStore', subproject: 'SubProject') -> None:
        self.options: options.MutableKeyedOptionDictType = {}
        self.subproject = subproject
        self.option_types: T.Dict[str, T.Callable[..., options.AnyOptionType]] = {
            '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,
        }
        self.optionstore = optionstore

    def process(self, option_file: str) -> None:
        try:
            with open(option_file, encoding='utf-8') as f:
                code = f.read()
        except UnicodeDecodeError as e:
            raise mesonlib.MesonException(f'Malformed option file {option_file!r} failed to parse as unicode: {e}')
        try:
            ast = mparser.Parser(code, 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.StringNode, 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.StringNode):
                    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 == '+' 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=options.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 = OptionKey.from_string(opt_name).evolve(subproject=self.subproject)
        if self.optionstore.is_reserved_name(key):
            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(opt_name, 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, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: StringArgs) -> options.UserOption:
        return options.UserStringOption(name, 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, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: BooleanArgs) -> options.UserOption:
        yielding, deprecated = args
        return options.UserBooleanOption(name, description, kwargs['value'], yielding=yielding, deprecated=deprecated)

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

    @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, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: IntegerArgs) -> options.UserOption:
        return options.UserIntegerOption(
            name, description, kwargs['value'], *args, min_value=kwargs['min'], max_value=kwargs['max'])

    @typed_kwargs(
        'string array option',
        KwargInfo('value', (ContainerTypeInfo(list, str), str, NoneType)),
        KwargInfo('choices', ContainerTypeInfo(list, str), default=[]),
    )
    def string_array_parser(self, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: StringArrayArgs) -> options.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 options.UserStringArrayOption(
            name, 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, name: str, description: str, args: T.Tuple[bool, _DEPRECATED_ARGS], kwargs: FeatureArgs) -> options.UserOption:
        return options.UserFeatureOption(name, description, kwargs['value'], *args)
