// 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.DEPENDENT);

  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.DEPENDENT;
      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 executing: ${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) {
          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) {
          throw new StateError(
              "Cannot process ready commands when not in Score 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);
  }
}