from axelrod.action import Action, actions_to_str

from axelrod.player import Player

from axelrod.strategy_transformers import (
    FinalTransformer,
    TrackHistoryTransformer,
)

C, D = Action.C, Action.D

class OmegaTFT(Player):
    """OmegaTFT modifies Tit For Tat in two ways:
    - checks for deadlock loops of alternating rounds of (C, D) and (D, C),
    and attempting to break them
    - uses a more sophisticated retaliation mechanism that is noise tolerant

    Names:

    - OmegaTFT: [Slany2007]_
    """

    name = "Omega TFT"
    classifier = {
        "memory_depth": float("inf"),
        "stochastic": False,
        "long_run_time": False,
        "inspects_source": False,
        "manipulates_source": False,
        "manipulates_state": False,
    }

    def __init__(
        self, deadlock_threshold: int = 3, randomness_threshold: int = 8
    ) -> None:
        super().__init__()
        self.deadlock_threshold = deadlock_threshold
        self.randomness_threshold = randomness_threshold
        self.randomness_counter = 0
        self.deadlock_counter = 0

    def strategy(self, opponent: Player) -> Action:
        """Actual strategy definition that determines player's action."""
        # Cooperate on the first move
        if not self.history:
            return C
        # TFT on round 2
        if len(self.history) == 1:
            return opponent.history[-1]

        # Are we deadlocked? (in a CD -> DC loop)
        if self.deadlock_counter >= self.deadlock_threshold:
            move = C
            if self.deadlock_counter == self.deadlock_threshold:
                self.deadlock_counter = self.deadlock_threshold + 1
            else:
                self.deadlock_counter = 0
        else:
            # Update counters
            if opponent.history[-2:] == [C, C]:
                self.randomness_counter -= 1
            # If the opponent's move changed, increase the counter
            if opponent.history[-2] != opponent.history[-1]:
                self.randomness_counter += 1
            # If the opponent's last move differed from mine,
            # increase the counter
            if self.history[-1] != opponent.history[-1]:
                self.randomness_counter += 1
            # Compare counts to thresholds
            # If randomness_counter exceeds Y, Defect for the remainder
            if self.randomness_counter >= self.randomness_threshold:
                move = D
            else:
                # TFT
                move = opponent.history[-1]
                # Check for deadlock
                if opponent.history[-2] != opponent.history[-1]:
                    self.deadlock_counter += 1
                else:
                    self.deadlock_counter = 0
        return move