# 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 . import coredata
    from .interpreterbase import TYPE_var, TYPE_kwargs
    from .interpreterbase 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: 'coredata.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 == '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=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)

    @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)
