from lib.abstract_walker import AbstractWalker


class FlatNode:
    def __init__(self, branch, commit, parent1=None, parent2=None) -> None:
        self.branch = branch
        self.commit = commit
        self.parent1 = parent1
        self.parent2 = parent2

    def __str__(self) -> str:
        p1_str = f" p1:{self.parent1.short_string()}" if self.parent1 else ""
        p2_str = f" p2:{self.parent2.short_string()}" if self.parent2 else ""
        return f"{self.branch} c:{self.commit.short_string()}{p1_str}{p2_str}"


class FlatTreeWalker(AbstractWalker):
    """While walking the tree, record the commits to do one after the other. These
    FlatNodes are in the end in the flats array."""

    def __init__(self, rebase_devel=False) -> None:
        super().__init__()
        self.flats = []
        # the rebase_devel won't work as such as rebasing the branch needs an explicit action
        self.rebase_devel = rebase_devel
        # remember the last merge point so we can know the parent of it for the root of the sources
        self.last_merge = None

    def add(self, branch, commit, parent1=None, parent2=None):
        self.flats.append(FlatNode(branch, commit, parent1, parent2))

    def handle_source_node(self, node) -> None:
        if self.rebase_devel and node.parent and node.parent.merged_into:
            self.add("devel", node.revision, node.parent.merged_into.revision)
        elif node.parent:
            self.add("devel", node.revision, node.parent.revision)
        elif self.last_merge:
            self.add("devel", node.revision, self.last_merge.parent.revision)

    def call(self, node, is_source) -> None:
        if is_source:
            self.handle_source_node(node)
            return
        if not node.parent:
            self.add("factory", node.revision)
            return
        if not node.merged:
            self.add("factory", node.revision, node.parent.revision)
            return
        self.add("factory", node.revision, node.parent.revision, node.merged.revision)

        self.last_merge = node