from antlr4.tree.Tree import ParseTree

from parser.PlSqlParser import PlSqlParser
from .visitor import Visitor

from .ast.hie_query import HierarchicalQueryNode
from .ast.token import TokenNode
from .ast.table_ref import TableRefNode
from .ast.selected_item import SelectedItemNode
from .ast.dot_id import DotIdNode
from .ast.relational_expression import RelationalExpressionNode
from .ast.prior_expression import PriorExpressionNode


class Translator(object):
    """
    Транслятор нод (ORA -> PG)
    """
    def __init__(self):
        self.visitor = Visitor(translator=self)

    def translate(self, tree: ParseTree):
        return self.visit(tree)

    def visit(self, ctx: ParseTree):
        return self.visitor.visit(ctx)

    def translate_hierarchical_query(self, ctx: PlSqlParser.Query_blockContext):
        """ """
        result = HierarchicalQueryNode()

        # обрабатываем selected элементы
        if ctx.selected_list().select_list_elements():
            # указано явное перечисление полей
            for selected_element in ctx.selected_list().select_list_elements():
                result.selected_elements.append(self.visit(selected_element))
        else:
            # SELECT * FROM
            result.selected_elements.append(TokenNode("*"))

        # обрабатываем выражение FROM

        for table_ref_ctx in ctx.from_clause().table_ref_list().table_ref():
            result.table_refs.append(self.visit(table_ref_ctx))

        # стартовая часть иерархического запроса
        start_part_ctx = ctx.hierarchical_query_clause().start_part() if ctx.hierarchical_query_clause() else None
        result.start_part = self.visit(start_part_ctx.condition()) if start_part_ctx else None

        # рекурсивная часть иерархического запроса
        hie_condition_ctx = ctx.hierarchical_query_clause().condition() if ctx.hierarchical_query_clause() else None
        result.hie_condition = self.visit(hie_condition_ctx) if hie_condition_ctx else None

        return result

    def translate_selected_list_elements(self, ctx: PlSqlParser.Select_list_elementsContext):
        """ Конвертация правила select_list_elements """
        if ctx.ASTERISK() is not None:
            return SelectedItemNode(name="*", table=self.visit(ctx.table_view_name()))

        alias = None
        if ctx.column_alias():
            alias = self.visit(
                ctx=ctx.column_alias().identifier() if ctx.column_alias().identifier() else \
                    ctx.column_alias().quoted_string()
            ).get_text()

        table = None
        name = None
        name_node = self.visit(ctx.expression())

        if isinstance(name_node, DotIdNode):
            table, name = name_node.left, name_node.right
        else:
            name = name_node.get_text()

        return SelectedItemNode(table=table, name=name, alias=alias)

    def translate_dot_id(self, ctx: PlSqlParser.General_element_partContext):
        """ """
        return DotIdNode(
            left=ctx.id_expression()[0].getText(),
            right=ctx.id_expression()[1].getText()
        )

    def translate_table_ref_aux(self, ctx: PlSqlParser.Table_ref_auxContext):
        """ """
        return TableRefNode(
            name=ctx.table_ref_aux_internal().getText(),
            alias=ctx.table_alias().getText() if ctx.table_alias() else None
        )

    def translate_relational_expression(self, ctx: PlSqlParser.Relational_expressionContext):
        """ """
        return RelationalExpressionNode(
            left=self.visit(ctx.relational_expression()[0]),
            op=ctx.relational_operator().getText(),
            right=self.visit(ctx.relational_expression()[1])
        )

    def translate_prior_expression(self, ctx: PlSqlParser.Unary_expressionContext):
        return PriorExpressionNode(self.visit(ctx.unary_expression()))

9befbccdde0758cc6ef0c35a2471ad4f5e47da73
<mask token>


class Translator(object):
    <mask token>

    def __init__(self):
        self.visitor = Visitor(translator=self)

    def translate(self, tree: ParseTree):
        return self.visit(tree)

    def visit(self, ctx: ParseTree):
        return self.visitor.visit(ctx)

    def translate_hierarchical_query(self, ctx: PlSqlParser.Query_blockContext
        ):
        """ """
        result = HierarchicalQueryNode()
        if ctx.selected_list().select_list_elements():
            for selected_element in ctx.selected_list().select_list_elements():
                result.selected_elements.append(self.visit(selected_element))
        else:
            result.selected_elements.append(TokenNode('*'))
        for table_ref_ctx in ctx.from_clause().table_ref_list().table_ref():
            result.table_refs.append(self.visit(table_ref_ctx))
        start_part_ctx = ctx.hierarchical_query_clause().start_part(
            ) if ctx.hierarchical_query_clause() else None
        result.start_part = self.visit(start_part_ctx.condition()
            ) if start_part_ctx else None
        hie_condition_ctx = ctx.hierarchical_query_clause().condition(
            ) if ctx.hierarchical_query_clause() else None
        result.hie_condition = self.visit(hie_condition_ctx
            ) if hie_condition_ctx else None
        return result
    <mask token>

    def translate_dot_id(self, ctx: PlSqlParser.General_element_partContext):
        """ """
        return DotIdNode(left=ctx.id_expression()[0].getText(), right=ctx.
            id_expression()[1].getText())
    <mask token>
    <mask token>

    def translate_prior_expression(self, ctx: PlSqlParser.
        Unary_expressionContext):
        return PriorExpressionNode(self.visit(ctx.unary_expression()))

<mask token>


class Translator(object):
    <mask token>

    def __init__(self):
        self.visitor = Visitor(translator=self)

    def translate(self, tree: ParseTree):
        return self.visit(tree)

    def visit(self, ctx: ParseTree):
        return self.visitor.visit(ctx)

    def translate_hierarchical_query(self, ctx: PlSqlParser.Query_blockContext
        ):
        """ """
        result = HierarchicalQueryNode()
        if ctx.selected_list().select_list_elements():
            for selected_element in ctx.selected_list().select_list_elements():
                result.selected_elements.append(self.visit(selected_element))
        else:
            result.selected_elements.append(TokenNode('*'))
        for table_ref_ctx in ctx.from_clause().table_ref_list().table_ref():
            result.table_refs.append(self.visit(table_ref_ctx))
        start_part_ctx = ctx.hierarchical_query_clause().start_part(
            ) if ctx.hierarchical_query_clause() else None
        result.start_part = self.visit(start_part_ctx.condition()
            ) if start_part_ctx else None
        hie_condition_ctx = ctx.hierarchical_query_clause().condition(
            ) if ctx.hierarchical_query_clause() else None
        result.hie_condition = self.visit(hie_condition_ctx
            ) if hie_condition_ctx else None
        return result

    def translate_selected_list_elements(self, ctx: PlSqlParser.
        Select_list_elementsContext):
        """ Конвертация правила select_list_elements """
        if ctx.ASTERISK() is not None:
            return SelectedItemNode(name='*', table=self.visit(ctx.
                table_view_name()))
        alias = None
        if ctx.column_alias():
            alias = self.visit(ctx=ctx.column_alias().identifier() if ctx.
                column_alias().identifier() else ctx.column_alias().
                quoted_string()).get_text()
        table = None
        name = None
        name_node = self.visit(ctx.expression())
        if isinstance(name_node, DotIdNode):
            table, name = name_node.left, name_node.right
        else:
            name = name_node.get_text()
        return SelectedItemNode(table=table, name=name, alias=alias)

    def translate_dot_id(self, ctx: PlSqlParser.General_element_partContext):
        """ """
        return DotIdNode(left=ctx.id_expression()[0].getText(), right=ctx.
            id_expression()[1].getText())

    def translate_table_ref_aux(self, ctx: PlSqlParser.Table_ref_auxContext):
        """ """
        return TableRefNode(name=ctx.table_ref_aux_internal().getText(),
            alias=ctx.table_alias().getText() if ctx.table_alias() else None)
    <mask token>

    def translate_prior_expression(self, ctx: PlSqlParser.
        Unary_expressionContext):
        return PriorExpressionNode(self.visit(ctx.unary_expression()))

<mask token>


class Translator(object):
    """
    Транслятор нод (ORA -> PG)
    """

    def __init__(self):
        self.visitor = Visitor(translator=self)

    def translate(self, tree: ParseTree):
        return self.visit(tree)

    def visit(self, ctx: ParseTree):
        return self.visitor.visit(ctx)

    def translate_hierarchical_query(self, ctx: PlSqlParser.Query_blockContext
        ):
        """ """
        result = HierarchicalQueryNode()
        if ctx.selected_list().select_list_elements():
            for selected_element in ctx.selected_list().select_list_elements():
                result.selected_elements.append(self.visit(selected_element))
        else:
            result.selected_elements.append(TokenNode('*'))
        for table_ref_ctx in ctx.from_clause().table_ref_list().table_ref():
            result.table_refs.append(self.visit(table_ref_ctx))
        start_part_ctx = ctx.hierarchical_query_clause().start_part(
            ) if ctx.hierarchical_query_clause() else None
        result.start_part = self.visit(start_part_ctx.condition()
            ) if start_part_ctx else None
        hie_condition_ctx = ctx.hierarchical_query_clause().condition(
            ) if ctx.hierarchical_query_clause() else None
        result.hie_condition = self.visit(hie_condition_ctx
            ) if hie_condition_ctx else None
        return result

    def translate_selected_list_elements(self, ctx: PlSqlParser.
        Select_list_elementsContext):
        """ Конвертация правила select_list_elements """
        if ctx.ASTERISK() is not None:
            return SelectedItemNode(name='*', table=self.visit(ctx.
                table_view_name()))
        alias = None
        if ctx.column_alias():
            alias = self.visit(ctx=ctx.column_alias().identifier() if ctx.
                column_alias().identifier() else ctx.column_alias().
                quoted_string()).get_text()
        table = None
        name = None
        name_node = self.visit(ctx.expression())
        if isinstance(name_node, DotIdNode):
            table, name = name_node.left, name_node.right
        else:
            name = name_node.get_text()
        return SelectedItemNode(table=table, name=name, alias=alias)

    def translate_dot_id(self, ctx: PlSqlParser.General_element_partContext):
        """ """
        return DotIdNode(left=ctx.id_expression()[0].getText(), right=ctx.
            id_expression()[1].getText())

    def translate_table_ref_aux(self, ctx: PlSqlParser.Table_ref_auxContext):
        """ """
        return TableRefNode(name=ctx.table_ref_aux_internal().getText(),
            alias=ctx.table_alias().getText() if ctx.table_alias() else None)

    def translate_relational_expression(self, ctx: PlSqlParser.
        Relational_expressionContext):
        """ """
        return RelationalExpressionNode(left=self.visit(ctx.
            relational_expression()[0]), op=ctx.relational_operator().
            getText(), right=self.visit(ctx.relational_expression()[1]))

    def translate_prior_expression(self, ctx: PlSqlParser.
        Unary_expressionContext):
        return PriorExpressionNode(self.visit(ctx.unary_expression()))

from antlr4.tree.Tree import ParseTree
from parser.PlSqlParser import PlSqlParser
from .visitor import Visitor
from .ast.hie_query import HierarchicalQueryNode
from .ast.token import TokenNode
from .ast.table_ref import TableRefNode
from .ast.selected_item import SelectedItemNode
from .ast.dot_id import DotIdNode
from .ast.relational_expression import RelationalExpressionNode
from .ast.prior_expression import PriorExpressionNode


class Translator(object):
    """
    Транслятор нод (ORA -> PG)
    """

    def __init__(self):
        self.visitor = Visitor(translator=self)

    def translate(self, tree: ParseTree):
        return self.visit(tree)

    def visit(self, ctx: ParseTree):
        return self.visitor.visit(ctx)

    def translate_hierarchical_query(self, ctx: PlSqlParser.Query_blockContext
        ):
        """ """
        result = HierarchicalQueryNode()
        if ctx.selected_list().select_list_elements():
            for selected_element in ctx.selected_list().select_list_elements():
                result.selected_elements.append(self.visit(selected_element))
        else:
            result.selected_elements.append(TokenNode('*'))
        for table_ref_ctx in ctx.from_clause().table_ref_list().table_ref():
            result.table_refs.append(self.visit(table_ref_ctx))
        start_part_ctx = ctx.hierarchical_query_clause().start_part(
            ) if ctx.hierarchical_query_clause() else None
        result.start_part = self.visit(start_part_ctx.condition()
            ) if start_part_ctx else None
        hie_condition_ctx = ctx.hierarchical_query_clause().condition(
            ) if ctx.hierarchical_query_clause() else None
        result.hie_condition = self.visit(hie_condition_ctx
            ) if hie_condition_ctx else None
        return result

    def translate_selected_list_elements(self, ctx: PlSqlParser.
        Select_list_elementsContext):
        """ Конвертация правила select_list_elements """
        if ctx.ASTERISK() is not None:
            return SelectedItemNode(name='*', table=self.visit(ctx.
                table_view_name()))
        alias = None
        if ctx.column_alias():
            alias = self.visit(ctx=ctx.column_alias().identifier() if ctx.
                column_alias().identifier() else ctx.column_alias().
                quoted_string()).get_text()
        table = None
        name = None
        name_node = self.visit(ctx.expression())
        if isinstance(name_node, DotIdNode):
            table, name = name_node.left, name_node.right
        else:
            name = name_node.get_text()
        return SelectedItemNode(table=table, name=name, alias=alias)

    def translate_dot_id(self, ctx: PlSqlParser.General_element_partContext):
        """ """
        return DotIdNode(left=ctx.id_expression()[0].getText(), right=ctx.
            id_expression()[1].getText())

    def translate_table_ref_aux(self, ctx: PlSqlParser.Table_ref_auxContext):
        """ """
        return TableRefNode(name=ctx.table_ref_aux_internal().getText(),
            alias=ctx.table_alias().getText() if ctx.table_alias() else None)

    def translate_relational_expression(self, ctx: PlSqlParser.
        Relational_expressionContext):
        """ """
        return RelationalExpressionNode(left=self.visit(ctx.
            relational_expression()[0]), op=ctx.relational_operator().
            getText(), right=self.visit(ctx.relational_expression()[1]))

    def translate_prior_expression(self, ctx: PlSqlParser.
        Unary_expressionContext):
        return PriorExpressionNode(self.visit(ctx.unary_expression()))

from antlr4.tree.Tree import ParseTree

from parser.PlSqlParser import PlSqlParser
from .visitor import Visitor

from .ast.hie_query import HierarchicalQueryNode
from .ast.token import TokenNode
from .ast.table_ref import TableRefNode
from .ast.selected_item import SelectedItemNode
from .ast.dot_id import DotIdNode
from .ast.relational_expression import RelationalExpressionNode
from .ast.prior_expression import PriorExpressionNode


class Translator(object):
    """
    Транслятор нод (ORA -> PG)
    """
    def __init__(self):
        self.visitor = Visitor(translator=self)

    def translate(self, tree: ParseTree):
        return self.visit(tree)

    def visit(self, ctx: ParseTree):
        return self.visitor.visit(ctx)

    def translate_hierarchical_query(self, ctx: PlSqlParser.Query_blockContext):
        """ """
        result = HierarchicalQueryNode()

        # обрабатываем selected элементы
        if ctx.selected_list().select_list_elements():
            # указано явное перечисление полей
            for selected_element in ctx.selected_list().select_list_elements():
                result.selected_elements.append(self.visit(selected_element))
        else:
            # SELECT * FROM
            result.selected_elements.append(TokenNode("*"))

        # обрабатываем выражение FROM

        for table_ref_ctx in ctx.from_clause().table_ref_list().table_ref():
            result.table_refs.append(self.visit(table_ref_ctx))

        # стартовая часть иерархического запроса
        start_part_ctx = ctx.hierarchical_query_clause().start_part() if ctx.hierarchical_query_clause() else None
        result.start_part = self.visit(start_part_ctx.condition()) if start_part_ctx else None

        # рекурсивная часть иерархического запроса
        hie_condition_ctx = ctx.hierarchical_query_clause().condition() if ctx.hierarchical_query_clause() else None
        result.hie_condition = self.visit(hie_condition_ctx) if hie_condition_ctx else None

        return result

    def translate_selected_list_elements(self, ctx: PlSqlParser.Select_list_elementsContext):
        """ Конвертация правила select_list_elements """
        if ctx.ASTERISK() is not None:
            return SelectedItemNode(name="*", table=self.visit(ctx.table_view_name()))

        alias = None
        if ctx.column_alias():
            alias = self.visit(
                ctx=ctx.column_alias().identifier() if ctx.column_alias().identifier() else \
                    ctx.column_alias().quoted_string()
            ).get_text()

        table = None
        name = None
        name_node = self.visit(ctx.expression())

        if isinstance(name_node, DotIdNode):
            table, name = name_node.left, name_node.right
        else:
            name = name_node.get_text()

        return SelectedItemNode(table=table, name=name, alias=alias)

    def translate_dot_id(self, ctx: PlSqlParser.General_element_partContext):
        """ """
        return DotIdNode(
            left=ctx.id_expression()[0].getText(),
            right=ctx.id_expression()[1].getText()
        )

    def translate_table_ref_aux(self, ctx: PlSqlParser.Table_ref_auxContext):
        """ """
        return TableRefNode(
            name=ctx.table_ref_aux_internal().getText(),
            alias=ctx.table_alias().getText() if ctx.table_alias() else None
        )

    def translate_relational_expression(self, ctx: PlSqlParser.Relational_expressionContext):
        """ """
        return RelationalExpressionNode(
            left=self.visit(ctx.relational_expression()[0]),
            op=ctx.relational_operator().getText(),
            right=self.visit(ctx.relational_expression()[1])
        )

    def translate_prior_expression(self, ctx: PlSqlParser.Unary_expressionContext):
        return PriorExpressionNode(self.visit(ctx.unary_expression()))
