# Copyright 2013-2014 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 re
import typing as T

from . import coredata
from . import mesonlib
from . import mparser
from . import mlog
from .interpreterbase import FeatureNew, typed_pos_args, typed_kwargs, ContainerTypeInfo, KwargInfo, permittedKwargs
if T.TYPE_CHECKING:
    from .interpreterbase import TV_func, TYPE_var, TYPE_kwargs
    from typing_extensions import TypedDict
    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': T.Union[bool, T.Dict[str, str], T.List[str]],
        })
    ParserArgs = TypedDict('ParserArgs', {
        'yield': bool,
        'choices': T.Optional[T.List[str]],
        'value': object,
        'min': T.Optional[int],
        'max': T.Optional[int],
        })


class OptionException(mesonlib.MesonException):
    pass


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


class OptionInterpreter:
    def __init__(self, subproject: str) -> None:
        self.options: 'coredata.KeyedOptionDictType' = {}
        self.subproject = subproject
        self.option_types = {'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
        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
        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),
                  KwargInfo('description', str, default=''),
                  KwargInfo('yield', bool, default=coredata.default_yielding, since='0.45.0'),
                  KwargInfo('choices', (ContainerTypeInfo(list, str), type(None))),
                  KwargInfo('value', object),
                  KwargInfo('min', (int, type(None))),
                  KwargInfo('max', (int, type(None))),
                  KwargInfo('deprecated', (bool, ContainerTypeInfo(dict, str), ContainerTypeInfo(list, str)),
                            default=False, since='0.60.0')
                  )
    @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.get(opt_type)
        if not parser:
            raise OptionException(f'Unknown type {opt_type}.')
        description = kwargs['description'] or opt_name

        # Only keep in kwargs arguments that are used by option type's parser
        # because they use @permittedKwargs().
        known_parser_kwargs = {'value', 'choices', 'yield', 'min', 'max'}
        parser_kwargs = {k: v for k, v in kwargs.items() if k in known_parser_kwargs and v is not None}
        opt = parser(description, T.cast('ParserArgs', parser_kwargs))
        opt.deprecated = kwargs['deprecated']

        if key in self.options:
            mlog.deprecation(f'Option {opt_name} already exists.')
        self.options[key] = opt

    @permittedKwargs({'value', 'yield'})
    def string_parser(self, description: str, kwargs: 'ParserArgs') -> coredata.UserOption:
        value = kwargs.get('value', '')
        return coredata.UserStringOption(description, value, kwargs['yield'])

    @permittedKwargs({'value', 'yield'})
    def boolean_parser(self, description: str, kwargs: 'ParserArgs') -> coredata.UserOption:
        value = kwargs.get('value', True)
        return coredata.UserBooleanOption(description, value, kwargs['yield'])

    @permittedKwargs({'value', 'yield', 'choices'})
    def combo_parser(self, description: str, kwargs: 'ParserArgs') -> coredata.UserOption:
        choices = kwargs.get('choices')
        if not choices:
            raise OptionException('Combo option missing "choices" keyword.')
        value = kwargs.get('value', choices[0])
        return coredata.UserComboOption(description, choices, value, kwargs['yield'])

    @permittedKwargs({'value', 'min', 'max', 'yield'})
    def integer_parser(self, description: str, kwargs: 'ParserArgs') -> coredata.UserOption:
        value = kwargs.get('value')
        if value is None:
            raise OptionException('Integer option must contain value argument.')
        inttuple = (kwargs.get('min'), kwargs.get('max'), value)
        return coredata.UserIntegerOption(description, inttuple, kwargs['yield'])

    @permittedKwargs({'value', 'yield', 'choices'})
    def string_array_parser(self, description: str, kwargs: 'ParserArgs') -> coredata.UserOption:
        choices = kwargs.get('choices', [])
        value = kwargs.get('value', choices)
        if not isinstance(value, list):
            raise OptionException('Array choices must be passed as an array.')
        return coredata.UserArrayOption(description, value,
                                        choices=choices,
                                        yielding=kwargs['yield'])

    @permittedKwargs({'value', 'yield'})
    def feature_parser(self, description: str, kwargs: 'ParserArgs') -> coredata.UserOption:
        value = kwargs.get('value', 'auto')
        return coredata.UserFeatureOption(description, value, kwargs['yield'])
