from typing import List, Optional

from axelrod.action import Action

from axelrod.player import Player

Vector = List[float]

C, D = Action.C, Action.D

class Prober4(Player):
    """
    Plays C, C, D, C, D, D, D, C, C, D, C, D, C, C, D, C, D, D, C, D initially.
    Counts retaliating and provocative defections of the opponent.
    If the absolute difference between the counts is smaller or equal to 2,
    defects forever.
    Otherwise plays C for the next 5 turns and TFT for the rest of the game.

    Names:

    - Prober 4: [Prison1998]_
    """

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

    def __init__(self) -> None:
        super().__init__()
        self.init_sequence = [
            C,
            C,
            D,
            C,
            D,
            D,
            D,
            C,
            C,
            D,
            C,
            D,
            C,
            C,
            D,
            C,
            D,
            D,
            C,
            D,
        ]
        self.just_Ds = 0
        self.unjust_Ds = 0
        self.turned_defector = False

    def strategy(self, opponent: Player) -> Action:
        """Actual strategy definition that determines player's action."""
        if not self.history:
            return self.init_sequence[0]
        turn = len(self.history)
        if turn < len(self.init_sequence):
            if opponent.history[-1] == D:
                if self.history[-1] == D:
                    self.just_Ds += 1
                if self.history[-1] == C:
                    self.unjust_Ds += 1
            return self.init_sequence[turn]
        if turn == len(self.init_sequence):
            diff_in_Ds = abs(self.just_Ds - self.unjust_Ds)
            self.turned_defector = diff_in_Ds <= 2
        if self.turned_defector:
            return D
        if not self.turned_defector:
            if turn < len(self.init_sequence) + 5:
                return C
            return D if opponent.history[-1] == D else C