// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

part of hearts;

class HeartsCommand extends GameCommand {
  // Usually this constructor is used when reading from a log/syncbase.
  HeartsCommand(String phase, String data)
      : super(phase, data, simultaneity: computeSimul(phase));

  HeartsCommand.fromCommand(String cmd)
      : super(cmd.split("|")[0], cmd.split("|")[1],
            simultaneity: computeSimul(cmd.split("|")[0]));

  // The following constructors are used for the player generating the HeartsCommand.
  HeartsCommand.deal(int playerId, List<Card> cards)
      : super("Deal", computeDeal(playerId, cards),
            simultaneity: SimulLevel.INDEPENDENT);

  HeartsCommand.pass(int senderId, List<Card> cards)
      : super("Pass", computePass(senderId, cards),
            simultaneity: SimulLevel.INDEPENDENT);

  HeartsCommand.take(int takerId)
      : super("Take", computeTake(takerId),
            simultaneity: SimulLevel.INDEPENDENT);

  HeartsCommand.play(int playerId, Card c)
      : super("Play", computePlay(playerId, c),
            simultaneity: SimulLevel.TURN_BASED);

  HeartsCommand.ready(int playerId)
      : super("Ready", computeReady(playerId),
            simultaneity: SimulLevel.INDEPENDENT);

  static SimulLevel computeSimul(String phase) {
    switch (phase) {
      case "Deal":
        return SimulLevel.INDEPENDENT;
      case "Pass":
        return SimulLevel.INDEPENDENT;
      case "Take":
        return SimulLevel.INDEPENDENT;
      case "Play":
        return SimulLevel.TURN_BASED;
      case "Ready":
        return SimulLevel.INDEPENDENT;
      default:
        print(phase);
        assert(false); // How could this have happened?
        return null;
    }
  }

  static String computeDeal(int playerId, List<Card> cards) {
    StringBuffer buff = new StringBuffer();
    buff.write("${playerId}:");
    cards.forEach((card) => buff.write("${card.toString()}:"));
    buff.write("END");
    return buff.toString();
  }

  static String computePass(int senderId, List<Card> cards) {
    StringBuffer buff = new StringBuffer();
    buff.write("${senderId}:");
    cards.forEach((card) => buff.write("${card.toString()}:"));
    buff.write("END");
    return buff.toString();
  }

  static String computeTake(int takerId) {
    return "${takerId}:END";
  }

  static String computePlay(int playerId, Card c) {
    return "${playerId}:${c.toString()}:END";
  }

  static String computeReady(int playerId) {
    return "${playerId}:END";
  }

  @override
  bool canExecute(Game g) {
    // TODO(alexfandrianto): This is very similar to execute, but without the
    // mutations. It's possible to use a shared function to simplify/combine the
    // logic.
    HeartsGame game = g as HeartsGame;

    print("HeartsCommand is checking: ${data}");
    List<String> parts = data.split(":");
    switch (phase) {
      case "Deal":
        if (game.phase != HeartsPhase.Deal) {
          return false;
        }
        // Deal appends cards to playerId's hand.
        int playerId = int.parse(parts[0]);
        List<Card> hand = game.cardCollections[playerId];
        if (hand.length + parts.length - 3 > 13) {
          return false;
        }

        // The last part is 'END', but the rest are cards.
        for (int i = 1; i < parts.length - 1; i++) {
          Card c = new Card.fromString(parts[i]);
          bool canTransfer = this.transferCheck(game.deck, hand, c);
          if (!canTransfer) {
            return false;
          }
        }
        return true;
      case "Pass":
        if (game.phase != HeartsPhase.Pass) {
          return false;
        }
        // Pass moves a set of cards from senderId to receiverId.
        int senderId = int.parse(parts[0]);
        int receiverId = senderId + HeartsGame.OFFSET_PASS;
        List<Card> handS = game.cardCollections[senderId];
        List<Card> handR = game.cardCollections[receiverId];

        int numPassing = parts.length - 2; // not senderId and not end
        if (numPassing != 3) {
          return false;
        }

        // The last part is 'END', but the rest are cards.
        for (int i = 1; i < parts.length - 1; i++) {
          Card c = new Card.fromString(parts[i]);
          bool canTransfer = this.transferCheck(handS, handR, c);
          if (!canTransfer) {
            return false;
          }
        }
        return true;
      case "Take":
        if (game.phase != HeartsPhase.Take) {
          return false;
        }
        return true;
      case "Play":
        if (game.phase != HeartsPhase.Play) {
          return false;
        }

        // Play the card from the player's hand to their play pile.
        int playerId = int.parse(parts[0]);
        int targetId = playerId + HeartsGame.OFFSET_PLAY;
        List<Card> hand = game.cardCollections[playerId];
        List<Card> discard = game.cardCollections[targetId];

        Card c = new Card.fromString(parts[1]);

        // If the card isn't valid, then we have an error.
        String reason = game.canPlay(playerId, c);
        if (reason != null) {
          return false;
        }
        bool canTransfer = this.transferCheck(hand, discard, c);
        return canTransfer;
      case "Ready":
        if (game.hasGameEnded) {
          return false;
        }
        if (game.phase != HeartsPhase.Score &&
            game.phase != HeartsPhase.StartGame) {
          return false;
        }
        return true;
      default:
        print(data);
        assert(false); // How could this have happened?
        return false;
    }
  }

  @override
  void execute(Game g) {
    HeartsGame game = g as HeartsGame;

    print("HeartsCommand is executing: ${data}");
    List<String> parts = data.split(":");
    switch (phase) {
      case "Deal":
        if (game.phase != HeartsPhase.Deal) {
          throw new StateError(
              "Cannot process deal commands when not in Deal phase");
        }
        // Deal appends cards to playerId's hand.
        int playerId = int.parse(parts[0]);
        List<Card> hand = game.cardCollections[playerId];
        if (hand.length + parts.length - 3 > 13) {
          throw new StateError("Cannot deal more than 13 cards to a hand");
        }

        // The last part is 'END', but the rest are cards.
        for (int i = 1; i < parts.length - 1; i++) {
          Card c = new Card.fromString(parts[i]);
          this.transfer(game.deck, hand, c);
        }
        return;
      case "Pass":
        if (game.phase != HeartsPhase.Pass) {
          throw new StateError(
              "Cannot process pass commands when not in Pass phase");
        }
        // Pass moves a set of cards from senderId to receiverId.
        int senderId = int.parse(parts[0]);
        int receiverId = senderId + HeartsGame.OFFSET_PASS;
        List<Card> handS = game.cardCollections[senderId];
        List<Card> handR = game.cardCollections[receiverId];

        int numPassing = parts.length - 2; // not senderId and not end
        if (numPassing != 3) {
          throw new StateError("Must pass 3 cards, attempted ${numPassing}");
        }

        // The last part is 'END', but the rest are cards.
        for (int i = 1; i < parts.length - 1; i++) {
          Card c = new Card.fromString(parts[i]);
          this.transfer(handS, handR, c);
        }
        return;
      case "Take":
        if (game.phase != HeartsPhase.Take) {
          throw new StateError(
              "Cannot process take commands when not in Take phase");
        }
        int takerId = int.parse(parts[0]);
        int senderPile = game.getTakeTarget(takerId) + HeartsGame.OFFSET_PASS;
        List<Card> handT = game.cardCollections[takerId];
        List<Card> handS = game.cardCollections[senderPile];
        handT.addAll(handS);
        handS.clear();
        return;
      case "Play":
        if (game.phase != HeartsPhase.Play) {
          throw new StateError(
              "Cannot process play commands when not in Play phase");
        }

        // Play the card from the player's hand to their play pile.
        int playerId = int.parse(parts[0]);
        int targetId = playerId + HeartsGame.OFFSET_PLAY;
        List<Card> hand = game.cardCollections[playerId];
        List<Card> discard = game.cardCollections[targetId];

        Card c = new Card.fromString(parts[1]);

        // If the card isn't valid, then we have an error.
        String reason = game.canPlay(playerId, c);
        if (reason != null) {
          throw new StateError(
              "Player ${playerId} cannot play ${c.toString()} because ${reason}");
        }
        this.transfer(hand, discard, c);
        return;
      case "Ready":
        if (game.hasGameEnded) {
          throw new StateError(
              "Game has already ended. Start a new one to play again.");
        }
        if (game.phase != HeartsPhase.Score &&
            game.phase != HeartsPhase.StartGame) {
          throw new StateError(
              "Cannot process ready commands when not in Score or StartGame phase");
        }
        int playerId = int.parse(parts[0]);
        game.setReady(playerId);
        return;
      default:
        print(data);
        assert(false); // How could this have happened?
    }
  }

  void transfer(List<Card> sender, List<Card> receiver, Card c) {
    if (!sender.contains(c)) {
      throw new StateError(
          "Sender ${sender.toString()} lacks Card ${c.toString()}");
    }
    sender.remove(c);
    receiver.add(c);
  }

  bool transferCheck(List<Card> sender, List<Card> receiver, Card c) {
    return sender.contains(c);
  }
}
