#  Copyright (c) PARRRATE T&V 2021. All rights reserved.

from bu4.evaluation.constructs.evaluable import Evaluable
from bu4.evaluation.constructs.evalue import EValue
from bu4.evaluation.targets.avtarget import AVTarget

__all__ = ('AfterValue',)


class AfterValue(Evaluable):
    def __init__(self, evaluable: Evaluable, target: AVTarget):
        self.evaluable = evaluable
        self.target = target

    def next(self) -> Evaluable:
        if isinstance(self.evaluable, EValue):
            if isinstance(self.target, AVChain):
                self.evaluable, self.target = self.target.target.given(self.evaluable), self.target.aftertarget
                return self
            return self.target.given(self.evaluable)
        if isinstance(self.evaluable, AfterValue):
            self.evaluable, self.target = self.evaluable.evaluable, AVChain(self.evaluable.target, self.target)
        self.evaluable = self.evaluable.next()
        return self

    def __str__(self):
        return f'{self.evaluable}->{self.target}'


class AVChain(AVTarget):
    def __init__(self, target: AVTarget, aftertarget: AVTarget):
        self.target = target
        self.aftertarget = aftertarget

    def given(self, value: EValue) -> Evaluable:
        return AfterValue(self.target.given(value), self.aftertarget)

    def __str__(self):
        return f'{self.target}->{self.aftertarget}'