// 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 solitaire;

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

  SolitaireCommand.fromCommand(String cmd)
      : super(cmd.split("|")[0], cmd.split("|")[1],
            simultaneity: SimulLevel.turnBased);

  // The following constructors are used for the player generating the SolitaireCommand.
  SolitaireCommand.deal(List<Card> allCards)
      : super("Deal", computeDeal(allCards),
            simultaneity: SimulLevel.turnBased);

  SolitaireCommand.move(Card target, int targetPile)
      : super("Move", computeMove(target, targetPile),
            simultaneity: SimulLevel.turnBased);

  SolitaireCommand.draw()
      : super("Draw", computeDraw(), simultaneity: SimulLevel.turnBased);

  SolitaireCommand.flip(int targetPile)
      : super("Flip", computeFlip(targetPile),
            simultaneity: SimulLevel.turnBased);

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

  // Note: Depending on the target's position w.r.t. the targetPile, this may
  // actually move a group of cards instead.
  static String computeMove(Card target, int targetPile) {
    return "${target.toString()}:$targetPile:END";
  }

  // Note: If there are no cards to draw, this will reset the draw pile.
  static String computeDraw() {
    return "END";
  }

  static String computeFlip(int targetPile) {
    return "$targetPile: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.
    SolitaireGame game = g as SolitaireGame;

    print("SolitaireCommand is checking: $command");
    List<String> parts = data.split(":");
    switch (phase) {
      case "Deal":
        return game.phase == SolitairePhase.deal && parts.length - 1 == 52;
      case "Move":
        if (game.phase != SolitairePhase.play) {
          return false;
        }

        // Move the card to the pile.
        Card c = new Card.fromString(parts[0]);
        int targetId = int.parse(parts[1]);
        int sourceId = game.findCard(c);
        if (sourceId == -1) {
          return false;
        }
        if (targetId < 0 || targetId >= game.cardCollections.length) {
          return false;
        }
        List<Card> source = game.cardCollections[sourceId];
        List<Card> dest = game.cardCollections[targetId];

        // If the card isn't valid, then we have an error.
        String reason = game.canPlay(c, dest);
        if (reason != null) {
          return false;
        }
        bool canTransfer = this.transferCheck(source, dest, c);
        return canTransfer;
      case "Draw":
        if (game.phase != SolitairePhase.play) {
          return false;
        }

        List<Card> drawPile = game.cardCollections[SolitaireGame.offsetDraw];
        List<Card> discardPile =
            game.cardCollections[SolitaireGame.offsetDiscard];

        return drawPile.length > 0 || discardPile.length > 0;
      case "Flip":
        if (game.phase != SolitairePhase.play) {
          return false;
        }

        int flipId = int.parse(parts[0]);
        if (flipId < 0 || flipId >= 7) {
          return false;
        }

        List<Card> flipSource =
            game.cardCollections[SolitaireGame.offsetDown + flipId];
        List<Card> flipDest =
            game.cardCollections[SolitaireGame.offsetUp + flipId];

        return flipDest.length == 0 && flipSource.length > 0;
      default:
        print(data);
        assert(false); // How could this have happened?
        return false;
    }
  }

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

    print("SolitaireCommand is executing: $command");
    List<String> parts = data.split(":");
    switch (phase) {
      case "Deal":
        if (game.phase != SolitairePhase.deal) {
          throw new StateError(
              "Cannot process deal commands when not in Deal phase");
        }
        if (parts.length - 1 != 52) {
          throw new StateError(
              "Not enough cards dealt. Need 52, got ${parts.length - 1}");
        }

        // Deal fills out each of the down cards with one of each up card.
        int index = 0;
        for (int i = 0; i < 7; i++) {
          for (int j = 0; j < i; j++) {
            this.transfer(
                game.deck,
                game.cardCollections[SolitaireGame.offsetDown + i],
                new Card.fromString(parts[index]));
            index++;
          }
          this.transfer(
              game.deck,
              game.cardCollections[SolitaireGame.offsetUp + i],
              new Card.fromString(parts[index]));
          index++;
        }

        // The remaining cards are for the draw pile.
        for (; index < 52; index++) {
          this.transfer(
              game.deck,
              game.cardCollections[SolitaireGame.offsetDraw],
              new Card.fromString(parts[index]));
        }
        return;
      case "Move":
        if (game.phase != SolitairePhase.play) {
          throw new StateError(
              "Cannot process move commands when not in Play phase");
        }

        // Move the card to the pile.
        Card c = new Card.fromString(parts[0]);
        int targetId = int.parse(parts[1]);
        int sourceId = game.findCard(c);
        if (sourceId == -1) {
          throw new StateError("Cannot move unknown card ${c.toString()}");
        }
        if (targetId < 0 || targetId >= game.cardCollections.length) {
          throw new StateError("Cannot move to unknown pile $targetId");
        }
        List<Card> source = game.cardCollections[sourceId];
        List<Card> dest = game.cardCollections[targetId];

        // If the card isn't valid, then we have an error.
        String reason = game.canPlay(c, dest);
        if (reason != null) {
          throw new StateError(
              "Cannot move ${c.toString()} to Pile $targetId because $reason");
        }
        this.transferGroup(source, dest, c);
        return;
      case "Draw":
        if (game.phase != SolitairePhase.play) {
          throw new StateError(
              "Cannot process draw commands when not in Play phase");
        }

        List<Card> drawPile = game.cardCollections[SolitaireGame.offsetDraw];
        List<Card> discardPile =
            game.cardCollections[SolitaireGame.offsetDiscard];

        if (drawPile.length != 0) {
          this.transfer(drawPile, discardPile, drawPile[0]);
        } else if (discardPile.length != 0) {
          this.transferGroup(discardPile, drawPile, discardPile[0]);
        } else {
          throw new StateError("No cards left to draw");
        }
        return;
      case "Flip":
        if (game.phase != SolitairePhase.play) {
          throw new StateError(
              "Cannot process flip commands when not in Play phase");
        }

        int flipId = int.parse(parts[0]);
        if (flipId < 0 || flipId >= 7) {
          throw new StateError("Cannot process flip command for index $flipId");
        }

        List<Card> flipSource =
            game.cardCollections[SolitaireGame.offsetDown + flipId];
        List<Card> flipDest =
            game.cardCollections[SolitaireGame.offsetUp + flipId];

        if (flipDest.length != 0) {
          throw new StateError(
              "Cannot flip $flipId because destination has cards");
        }
        if (flipSource.length == 0) {
          throw new StateError(
              "Cannot flip $flipId because source has no cards");
        }
        this.transfer(flipSource, flipDest, flipSource[flipSource.length - 1]);
        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);
  }

  // Transfers every card from a certain cutoff card onwards.
  void transferGroup(List<Card> sender, List<Card> receiver, Card c) {
    int index = sender.indexOf(c);
    if (index == -1) {
      throw new StateError(
          "Sender ${sender.toString()} lacks Card ${c.toString()}");
    }
    List<Card> lost =
        new List<Card>.from(sender.getRange(index, sender.length));
    sender.removeRange(index, sender.length);
    receiver.addAll(lost);
  }

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