# Copyright 2016 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.

# This class contains the basic functionality needed to run any interpreter
# or an interpreter-based tool.

from .visitor import AstVisitor
from .. import mparser, mesonlib
from .. import environment

from ..interpreterbase import (
    MesonInterpreterObject,
    InterpreterBase,
    InvalidArguments,
    BreakRequest,
    ContinueRequest,
    default_resolve_key,
    TYPE_nvar,
    TYPE_nkwargs,
)

from ..mparser import (
    AndNode,
    ArgumentNode,
    ArithmeticNode,
    ArrayNode,
    AssignmentNode,
    BaseNode,
    ComparisonNode,
    ElementaryNode,
    EmptyNode,
    ForeachClauseNode,
    IdNode,
    IfClauseNode,
    IndexNode,
    MethodNode,
    NotNode,
    OrNode,
    PlusAssignmentNode,
    TernaryNode,
    UMinusNode,
)

import os, sys
import typing as T

class DontCareObject(MesonInterpreterObject):
    pass

class MockExecutable(MesonInterpreterObject):
    pass

class MockStaticLibrary(MesonInterpreterObject):
    pass

class MockSharedLibrary(MesonInterpreterObject):
    pass

class MockCustomTarget(MesonInterpreterObject):
    pass

class MockRunTarget(MesonInterpreterObject):
    pass

ADD_SOURCE = 0
REMOVE_SOURCE = 1

_T = T.TypeVar('_T')
_V = T.TypeVar('_V')

class AstInterpreter(InterpreterBase):
    def __init__(self, source_root: str, subdir: str, subproject: str, visitors: T.Optional[T.List[AstVisitor]] = None):
        super().__init__(source_root, subdir, subproject)
        self.visitors = visitors if visitors is not None else []
        self.processed_buildfiles = set() # type: T.Set[str]
        self.assignments = {}             # type: T.Dict[str, BaseNode]
        self.assign_vals = {}             # type: T.Dict[str, T.Any]
        self.reverse_assignment = {}      # type: T.Dict[str, BaseNode]
        self.funcs.update({'project': self.func_do_nothing,
                           'test': self.func_do_nothing,
                           'benchmark': self.func_do_nothing,
                           'install_headers': self.func_do_nothing,
                           'install_man': self.func_do_nothing,
                           'install_data': self.func_do_nothing,
                           'install_subdir': self.func_do_nothing,
                           'configuration_data': self.func_do_nothing,
                           'configure_file': self.func_do_nothing,
                           'find_program': self.func_do_nothing,
                           'include_directories': self.func_do_nothing,
                           'add_global_arguments': self.func_do_nothing,
                           'add_global_link_arguments': self.func_do_nothing,
                           'add_project_arguments': self.func_do_nothing,
                           'add_project_link_arguments': self.func_do_nothing,
                           'message': self.func_do_nothing,
                           'generator': self.func_do_nothing,
                           'error': self.func_do_nothing,
                           'run_command': self.func_do_nothing,
                           'assert': self.func_do_nothing,
                           'subproject': self.func_do_nothing,
                           'dependency': self.func_do_nothing,
                           'get_option': self.func_do_nothing,
                           'join_paths': self.func_do_nothing,
                           'environment': self.func_do_nothing,
                           'import': self.func_do_nothing,
                           'vcs_tag': self.func_do_nothing,
                           'add_languages': self.func_do_nothing,
                           'declare_dependency': self.func_do_nothing,
                           'files': self.func_do_nothing,
                           'executable': self.func_do_nothing,
                           'static_library': self.func_do_nothing,
                           'shared_library': self.func_do_nothing,
                           'library': self.func_do_nothing,
                           'build_target': self.func_do_nothing,
                           'custom_target': self.func_do_nothing,
                           'run_target': self.func_do_nothing,
                           'subdir': self.func_subdir,
                           'set_variable': self.func_do_nothing,
                           'get_variable': self.func_do_nothing,
                           'unset_variable': self.func_do_nothing,
                           'is_disabler': self.func_do_nothing,
                           'is_variable': self.func_do_nothing,
                           'disabler': self.func_do_nothing,
                           'gettext': self.func_do_nothing,
                           'jar': self.func_do_nothing,
                           'warning': self.func_do_nothing,
                           'shared_module': self.func_do_nothing,
                           'option': self.func_do_nothing,
                           'both_libraries': self.func_do_nothing,
                           'add_test_setup': self.func_do_nothing,
                           'find_library': self.func_do_nothing,
                           'subdir_done': self.func_do_nothing,
                           'alias_target': self.func_do_nothing,
                           'summary': self.func_do_nothing,
                           'range': self.func_do_nothing,
                           })

    def _unholder_args(self, args: _T, kwargs: _V) -> T.Tuple[_T, _V]:
        return args, kwargs

    def _holderify(self, res: _T) -> _T:
        return res

    def func_do_nothing(self, node: BaseNode, args: T.List[TYPE_nvar], kwargs: T.Dict[str, TYPE_nvar]) -> bool:
        return True

    def load_root_meson_file(self) -> None:
        super().load_root_meson_file()
        for i in self.visitors:
            self.ast.accept(i)

    def func_subdir(self, node: BaseNode, args: T.List[TYPE_nvar], kwargs: T.Dict[str, TYPE_nvar]) -> None:
        args = self.flatten_args(args)
        if len(args) != 1 or not isinstance(args[0], str):
            sys.stderr.write(f'Unable to evaluate subdir({args}) in AstInterpreter --> Skipping\n')
            return

        prev_subdir = self.subdir
        subdir = os.path.join(prev_subdir, args[0])
        absdir = os.path.join(self.source_root, subdir)
        buildfilename = os.path.join(subdir, environment.build_filename)
        absname = os.path.join(self.source_root, buildfilename)
        symlinkless_dir = os.path.realpath(absdir)
        build_file = os.path.join(symlinkless_dir, 'meson.build')
        if build_file in self.processed_buildfiles:
            sys.stderr.write('Trying to enter {} which has already been visited --> Skipping\n'.format(args[0]))
            return
        self.processed_buildfiles.add(build_file)

        if not os.path.isfile(absname):
            sys.stderr.write(f'Unable to find build file {buildfilename} --> Skipping\n')
            return
        with open(absname, encoding='utf-8') as f:
            code = f.read()
        assert(isinstance(code, str))
        try:
            codeblock = mparser.Parser(code, absname).parse()
        except mesonlib.MesonException as me:
            me.file = absname
            raise me

        self.subdir = subdir
        for i in self.visitors:
            codeblock.accept(i)
        self.evaluate_codeblock(codeblock)
        self.subdir = prev_subdir

    def method_call(self, node: BaseNode) -> bool:
        return True

    def evaluate_fstring(self, node: mparser.FormatStringNode) -> str:
        assert(isinstance(node, mparser.FormatStringNode))
        return node.value

    def evaluate_arithmeticstatement(self, cur: ArithmeticNode) -> int:
        self.evaluate_statement(cur.left)
        self.evaluate_statement(cur.right)
        return 0

    def evaluate_uminusstatement(self, cur: UMinusNode) -> int:
        self.evaluate_statement(cur.value)
        return 0

    def evaluate_ternary(self, node: TernaryNode) -> None:
        assert(isinstance(node, TernaryNode))
        self.evaluate_statement(node.condition)
        self.evaluate_statement(node.trueblock)
        self.evaluate_statement(node.falseblock)

    def evaluate_dictstatement(self, node: mparser.DictNode) -> TYPE_nkwargs:
        def resolve_key(node: mparser.BaseNode) -> str:
            if isinstance(node, mparser.StringNode):
                return node.value
            return '__AST_UNKNOWN__'
        arguments, kwargs = self.reduce_arguments(node.args, key_resolver=resolve_key)
        assert (not arguments)
        self.argument_depth += 1
        for key, value in kwargs.items():
            if isinstance(key, BaseNode):
                self.evaluate_statement(key)
        self.argument_depth -= 1
        return {}

    def evaluate_plusassign(self, node: PlusAssignmentNode) -> None:
        assert(isinstance(node, PlusAssignmentNode))
        # Cheat by doing a reassignment
        self.assignments[node.var_name] = node.value  # Save a reference to the value node
        if node.value.ast_id:
            self.reverse_assignment[node.value.ast_id] = node
        self.assign_vals[node.var_name] = self.evaluate_statement(node.value)

    def evaluate_indexing(self, node: IndexNode) -> int:
        return 0

    def unknown_function_called(self, func_name: str) -> None:
        pass

    def reduce_arguments(
                self,
                args: mparser.ArgumentNode,
                key_resolver: T.Callable[[mparser.BaseNode], str] = default_resolve_key,
                duplicate_key_error: T.Optional[str] = None,
            ) -> T.Tuple[T.List[TYPE_nvar], TYPE_nkwargs]:
        if isinstance(args, ArgumentNode):
            kwargs = {}  # type: T.Dict[str, TYPE_nvar]
            for key, val in args.kwargs.items():
                kwargs[key_resolver(key)] = val
            if args.incorrect_order():
                raise InvalidArguments('All keyword arguments must be after positional arguments.')
            return self.flatten_args(args.arguments), kwargs
        else:
            return self.flatten_args(args), {}

    def evaluate_comparison(self, node: ComparisonNode) -> bool:
        self.evaluate_statement(node.left)
        self.evaluate_statement(node.right)
        return False

    def evaluate_andstatement(self, cur: AndNode) -> bool:
        self.evaluate_statement(cur.left)
        self.evaluate_statement(cur.right)
        return False

    def evaluate_orstatement(self, cur: OrNode) -> bool:
        self.evaluate_statement(cur.left)
        self.evaluate_statement(cur.right)
        return False

    def evaluate_notstatement(self, cur: NotNode) -> bool:
        self.evaluate_statement(cur.value)
        return False

    def evaluate_foreach(self, node: ForeachClauseNode) -> None:
        try:
            self.evaluate_codeblock(node.block)
        except ContinueRequest:
            pass
        except BreakRequest:
            pass

    def evaluate_if(self, node: IfClauseNode) -> None:
        for i in node.ifs:
            self.evaluate_codeblock(i.block)
        if not isinstance(node.elseblock, EmptyNode):
            self.evaluate_codeblock(node.elseblock)

    def get_variable(self, varname: str) -> int:
        return 0

    def assignment(self, node: AssignmentNode) -> None:
        assert(isinstance(node, AssignmentNode))
        self.assignments[node.var_name] = node.value # Save a reference to the value node
        if node.value.ast_id:
            self.reverse_assignment[node.value.ast_id] = node
        self.assign_vals[node.var_name] = self.evaluate_statement(node.value) # Evaluate the value just in case

    def resolve_node(self, node: BaseNode, include_unknown_args: bool = False, id_loop_detect: T.Optional[T.List[str]] = None) -> T.Optional[T.Any]:
        def quick_resolve(n: BaseNode, loop_detect: T.Optional[T.List[str]] = None) -> T.Any:
            if loop_detect is None:
                loop_detect = []
            if isinstance(n, IdNode):
                assert isinstance(n.value, str)
                if n.value in loop_detect or n.value not in self.assignments:
                    return []
                return quick_resolve(self.assignments[n.value], loop_detect = loop_detect + [n.value])
            elif isinstance(n, ElementaryNode):
                return n.value
            else:
                return n

        if id_loop_detect is None:
            id_loop_detect = []
        result = None

        if not isinstance(node, BaseNode):
            return None

        assert node.ast_id
        if node.ast_id in id_loop_detect:
            return None # Loop detected
        id_loop_detect += [node.ast_id]

        # Try to evealuate the value of the node
        if isinstance(node, IdNode):
            result = quick_resolve(node)

        elif isinstance(node, ElementaryNode):
            result = node.value

        elif isinstance(node, NotNode):
            result = self.resolve_node(node.value, include_unknown_args, id_loop_detect)
            if isinstance(result, bool):
                result = not result

        elif isinstance(node, ArrayNode):
            result = [x for x in node.args.arguments]

        elif isinstance(node, ArgumentNode):
            result = [x for x in node.arguments]

        elif isinstance(node, ArithmeticNode):
            if node.operation != 'add':
                return None # Only handle string and array concats
            l = quick_resolve(node.left)
            r = quick_resolve(node.right)
            if isinstance(l, str) and isinstance(r, str):
                result = l + r # String concatenation detected
            else:
                result = self.flatten_args(l, include_unknown_args, id_loop_detect) + self.flatten_args(r, include_unknown_args, id_loop_detect)

        elif isinstance(node, MethodNode):
            src = quick_resolve(node.source_object)
            margs = self.flatten_args(node.args.arguments, include_unknown_args, id_loop_detect)
            mkwargs = {} # type: T.Dict[str, TYPE_nvar]
            try:
                if isinstance(src, str):
                    result = self.string_method_call(src, node.name, margs, mkwargs)
                elif isinstance(src, bool):
                    result = self.bool_method_call(src, node.name, margs, mkwargs)
                elif isinstance(src, int):
                    result = self.int_method_call(src, node.name, margs, mkwargs)
                elif isinstance(src, list):
                    result = self.array_method_call(src, node.name, margs, mkwargs)
                elif isinstance(src, dict):
                    result = self.dict_method_call(src, node.name, margs, mkwargs)
            except mesonlib.MesonException:
                return None

        # Ensure that the result is fully resolved (no more nodes)
        if isinstance(result, BaseNode):
            result = self.resolve_node(result, include_unknown_args, id_loop_detect)
        elif isinstance(result, list):
            new_res = []  # type: T.List[TYPE_nvar]
            for i in result:
                if isinstance(i, BaseNode):
                    resolved = self.resolve_node(i, include_unknown_args, id_loop_detect)
                    if resolved is not None:
                        new_res += self.flatten_args(resolved, include_unknown_args, id_loop_detect)
                else:
                    new_res += [i]
            result = new_res

        return result

    def flatten_args(self, args_raw: T.Union[TYPE_nvar, T.Sequence[TYPE_nvar]], include_unknown_args: bool = False, id_loop_detect: T.Optional[T.List[str]] = None) -> T.List[TYPE_nvar]:
        # Make sure we are always dealing with lists
        if isinstance(args_raw, list):
            args = args_raw
        else:
            args = [args_raw]

        flattend_args = []  # type: T.List[TYPE_nvar]

        # Resolve the contents of args
        for i in args:
            if isinstance(i, BaseNode):
                resolved = self.resolve_node(i, include_unknown_args, id_loop_detect)
                if resolved is not None:
                    if not isinstance(resolved, list):
                        resolved = [resolved]
                    flattend_args += resolved
            elif isinstance(i, (str, bool, int, float)) or include_unknown_args:
                flattend_args += [i]
        return flattend_args

    def flatten_kwargs(self, kwargs: T.Dict[str, TYPE_nvar], include_unknown_args: bool = False) -> T.Dict[str, TYPE_nvar]:
        flattend_kwargs = {}
        for key, val in kwargs.items():
            if isinstance(val, BaseNode):
                resolved = self.resolve_node(val, include_unknown_args)
                if resolved is not None:
                    flattend_kwargs[key] = resolved
            elif isinstance(val, (str, bool, int, float)) or include_unknown_args:
                flattend_kwargs[key] = val
        return flattend_kwargs
