# Copyright 2019 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 .. import mparser
from . import AstVisitor
import re
import typing as T

arithmic_map = {
    'add': '+',
    'sub': '-',
    'mod': '%',
    'mul': '*',
    'div': '/'
}

class AstPrinter(AstVisitor):
    def __init__(self, indent: int = 2, arg_newline_cutoff: int = 5):
        self.result = ''
        self.indent = indent
        self.arg_newline_cutoff = arg_newline_cutoff
        self.ci = ''
        self.is_newline = True
        self.last_level = 0

    def post_process(self) -> None:
        self.result = re.sub(r'\s+\n', '\n', self.result)

    def append(self, data: str, node: mparser.BaseNode) -> None:
        self.last_level = node.level
        if self.is_newline:
            self.result += ' ' * (node.level * self.indent)
        self.result += data
        self.is_newline = False

    def append_padded(self, data: str, node: mparser.BaseNode) -> None:
        if self.result[-1] not in [' ', '\n']:
            data = ' ' + data
        self.append(data + ' ', node)

    def newline(self) -> None:
        self.result += '\n'
        self.is_newline = True

    def visit_BooleanNode(self, node: mparser.BooleanNode) -> None:
        self.append('true' if node.value else 'false', node)

    def visit_IdNode(self, node: mparser.IdNode) -> None:
        assert isinstance(node.value, str)
        self.append(node.value, node)

    def visit_NumberNode(self, node: mparser.NumberNode) -> None:
        self.append(str(node.value), node)

    def visit_StringNode(self, node: mparser.StringNode) -> None:
        assert isinstance(node.value, str)
        self.append("'" + node.value + "'", node)

    def visit_ContinueNode(self, node: mparser.ContinueNode) -> None:
        self.append('continue', node)

    def visit_BreakNode(self, node: mparser.BreakNode) -> None:
        self.append('break', node)

    def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
        self.append('[', node)
        node.args.accept(self)
        self.append(']', node)

    def visit_DictNode(self, node: mparser.DictNode) -> None:
        self.append('{', node)
        node.args.accept(self)
        self.append('}', node)

    def visit_OrNode(self, node: mparser.OrNode) -> None:
        node.left.accept(self)
        self.append_padded('or', node)
        node.right.accept(self)

    def visit_AndNode(self, node: mparser.AndNode) -> None:
        node.left.accept(self)
        self.append_padded('and', node)
        node.right.accept(self)

    def visit_ComparisonNode(self, node: mparser.ComparisonNode) -> None:
        node.left.accept(self)
        self.append_padded(node.ctype, node)
        node.right.accept(self)

    def visit_ArithmeticNode(self, node: mparser.ArithmeticNode) -> None:
        node.left.accept(self)
        self.append_padded(arithmic_map[node.operation], node)
        node.right.accept(self)

    def visit_NotNode(self, node: mparser.NotNode) -> None:
        self.append_padded('not', node)
        node.value.accept(self)

    def visit_CodeBlockNode(self, node: mparser.CodeBlockNode) -> None:
        for i in node.lines:
            i.accept(self)
            self.newline()

    def visit_IndexNode(self, node: mparser.IndexNode) -> None:
        node.iobject.accept(self)
        self.append('[', node)
        node.index.accept(self)
        self.append(']', node)

    def visit_MethodNode(self, node: mparser.MethodNode) -> None:
        node.source_object.accept(self)
        self.append('.' + node.name + '(', node)
        node.args.accept(self)
        self.append(')', node)

    def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
        self.append(node.func_name + '(', node)
        node.args.accept(self)
        self.append(')', node)

    def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
        self.append(node.var_name + ' = ', node)
        node.value.accept(self)

    def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None:
        self.append(node.var_name + ' += ', node)
        node.value.accept(self)

    def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
        varnames = [x for x in node.varnames]
        self.append_padded('foreach', node)
        self.append_padded(', '.join(varnames), node)
        self.append_padded(':', node)
        node.items.accept(self)
        self.newline()
        node.block.accept(self)
        self.append('endforeach', node)

    def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
        prefix = ''
        for i in node.ifs:
            self.append_padded(prefix + 'if', node)
            prefix = 'el'
            i.accept(self)
        if not isinstance(node.elseblock, mparser.EmptyNode):
            self.append('else', node)
            node.elseblock.accept(self)
        self.append('endif', node)

    def visit_UMinusNode(self, node: mparser.UMinusNode) -> None:
        self.append_padded('-', node)
        node.value.accept(self)

    def visit_IfNode(self, node: mparser.IfNode) -> None:
        node.condition.accept(self)
        self.newline()
        node.block.accept(self)

    def visit_TernaryNode(self, node: mparser.TernaryNode) -> None:
        node.condition.accept(self)
        self.append_padded('?', node)
        node.trueblock.accept(self)
        self.append_padded(':', node)
        node.falseblock.accept(self)

    def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
        break_args = (len(node.arguments) + len(node.kwargs)) > self.arg_newline_cutoff
        for i in node.arguments + list(node.kwargs.values()):
            if not isinstance(i, (mparser.ElementaryNode, mparser.IndexNode)):
                break_args = True
        if break_args:
            self.newline()
        for i in node.arguments:
            i.accept(self)
            self.append(', ', node)
            if break_args:
                self.newline()
        for key, val in node.kwargs.items():
            key.accept(self)
            self.append_padded(':', node)
            val.accept(self)
            self.append(', ', node)
            if break_args:
                self.newline()
        if break_args:
            self.result = re.sub(r', \n$', '\n', self.result)
        else:
            self.result = re.sub(r', $', '', self.result)

class AstJSONPrinter(AstVisitor):
    def __init__(self) -> None:
        self.result = {}  # type: T.Dict[str, T.Any]
        self.current = self.result

    def _accept(self, key: str, node: mparser.BaseNode) -> None:
        old = self.current
        data = {}  # type: T.Dict[str, T.Any]
        self.current = data
        node.accept(self)
        self.current = old
        self.current[key] = data

    def _accept_list(self, key: str, nodes: T.Sequence[mparser.BaseNode]) -> None:
        old = self.current
        datalist = []  # type: T.List[T.Dict[str, T.Any]]
        for i in nodes:
            self.current = {}
            i.accept(self)
            datalist += [self.current]
        self.current = old
        self.current[key] = datalist

    def _raw_accept(self, node: mparser.BaseNode, data: T.Dict[str, T.Any]) -> None:
        old = self.current
        self.current = data
        node.accept(self)
        self.current = old

    def setbase(self, node: mparser.BaseNode) -> None:
        self.current['node'] = type(node).__name__
        self.current['lineno'] = node.lineno
        self.current['colno'] = node.colno
        self.current['end_lineno'] = node.end_lineno
        self.current['end_colno'] = node.end_colno

    def visit_default_func(self, node: mparser.BaseNode) -> None:
        self.setbase(node)

    def gen_ElementaryNode(self, node: mparser.ElementaryNode) -> None:
        self.current['value'] = node.value
        self.setbase(node)

    def visit_BooleanNode(self, node: mparser.BooleanNode) -> None:
        self.gen_ElementaryNode(node)

    def visit_IdNode(self, node: mparser.IdNode) -> None:
        self.gen_ElementaryNode(node)

    def visit_NumberNode(self, node: mparser.NumberNode) -> None:
        self.gen_ElementaryNode(node)

    def visit_StringNode(self, node: mparser.StringNode) -> None:
        self.gen_ElementaryNode(node)

    def visit_ArrayNode(self, node: mparser.ArrayNode) -> None:
        self._accept('args', node.args)
        self.setbase(node)

    def visit_DictNode(self, node: mparser.DictNode) -> None:
        self._accept('args', node.args)
        self.setbase(node)

    def visit_OrNode(self, node: mparser.OrNode) -> None:
        self._accept('left', node.left)
        self._accept('right', node.right)
        self.setbase(node)

    def visit_AndNode(self, node: mparser.AndNode) -> None:
        self._accept('left', node.left)
        self._accept('right', node.right)
        self.setbase(node)

    def visit_ComparisonNode(self, node: mparser.ComparisonNode) -> None:
        self._accept('left', node.left)
        self._accept('right', node.right)
        self.current['ctype'] = node.ctype
        self.setbase(node)

    def visit_ArithmeticNode(self, node: mparser.ArithmeticNode) -> None:
        self._accept('left', node.left)
        self._accept('right', node.right)
        self.current['op'] = arithmic_map[node.operation]
        self.setbase(node)

    def visit_NotNode(self, node: mparser.NotNode) -> None:
        self._accept('right', node.value)
        self.setbase(node)

    def visit_CodeBlockNode(self, node: mparser.CodeBlockNode) -> None:
        self._accept_list('lines', node.lines)
        self.setbase(node)

    def visit_IndexNode(self, node: mparser.IndexNode) -> None:
        self._accept('object', node.iobject)
        self._accept('index', node.index)
        self.setbase(node)

    def visit_MethodNode(self, node: mparser.MethodNode) -> None:
        self._accept('object', node.source_object)
        self._accept('args', node.args)
        self.current['name'] = node.name
        self.setbase(node)

    def visit_FunctionNode(self, node: mparser.FunctionNode) -> None:
        self._accept('args', node.args)
        self.current['name'] = node.func_name
        self.setbase(node)

    def visit_AssignmentNode(self, node: mparser.AssignmentNode) -> None:
        self._accept('value', node.value)
        self.current['var_name'] = node.var_name
        self.setbase(node)

    def visit_PlusAssignmentNode(self, node: mparser.PlusAssignmentNode) -> None:
        self._accept('value', node.value)
        self.current['var_name'] = node.var_name
        self.setbase(node)

    def visit_ForeachClauseNode(self, node: mparser.ForeachClauseNode) -> None:
        self._accept('items', node.items)
        self._accept('block', node.block)
        self.current['varnames'] = node.varnames
        self.setbase(node)

    def visit_IfClauseNode(self, node: mparser.IfClauseNode) -> None:
        self._accept_list('ifs', node.ifs)
        self._accept('else', node.elseblock)
        self.setbase(node)

    def visit_UMinusNode(self, node: mparser.UMinusNode) -> None:
        self._accept('right', node.value)
        self.setbase(node)

    def visit_IfNode(self, node: mparser.IfNode) -> None:
        self._accept('condition', node.condition)
        self._accept('block', node.block)
        self.setbase(node)

    def visit_TernaryNode(self, node: mparser.TernaryNode) -> None:
        self._accept('condition', node.condition)
        self._accept('true', node.trueblock)
        self._accept('false', node.falseblock)
        self.setbase(node)

    def visit_ArgumentNode(self, node: mparser.ArgumentNode) -> None:
        self._accept_list('positional', node.arguments)
        kwargs_list = []  # type: T.List[T.Dict[str, T.Dict[str, T.Any]]]
        for key, val in node.kwargs.items():
            key_res = {}  # type: T.Dict[str, T.Any]
            val_res = {}  # type: T.Dict[str, T.Any]
            self._raw_accept(key, key_res)
            self._raw_accept(val, val_res)
            kwargs_list += [{'key': key_res, 'val': val_res}]
        self.current['kwargs'] = kwargs_list
        self.setbase(node)
