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

#include "promise_example2.h"

#include <lib/fpromise/promise.h>
#include <lib/fpromise/single_threaded_executor.h>

#include <algorithm>
#include <memory>
#include <string>

#include "utils.h"

namespace promise_example2 {

// State for a two player game.
//
// Players do battle by simultaneously rolling dice in order to inflict
// damage upon their opponent over the course of several rounds until one
// or both players' hit points are depleted to 0.
//
// Players start with 100 hit points.  During each round, each player first
// rolls a Damage die (numbered 0 to 9) and an Effect die (numbered 0 to 3).
// If the Effect die comes up 0, the player casts a lightning spell and
// rolls an Effect Multiplier die (numbered 0 to 4) to determine the
// strength of the effect.
//
// The following calculation determines the damage dealt to the player's
// opponent:
//
//   if Damage die value is non-zero,
//     then opponent HP -= value of Damage die
//   if Effect die is zero (cast lighting),
//     then opponent HP -= value of Effect Multiplier die * 2 + 3
//
// Any dice that fly off the table during especially vigorous rolls are
// rerolled before damage is tallied.
struct game_state {
  int red_hp = 100;
  int blue_hp = 100;
};

// Rolls a die and waits for it to settle down then returns its value.
// This task might fail so the caller needs to be prepared to re-roll.
//
// This function demonstrates returning pending, error, and ok states as well
// as task suspension.
auto roll_die(std::string player, std::string type, int number_of_sides) {
  return fpromise::make_promise(
      [player, type, number_of_sides](fpromise::context& context) -> fpromise::result<int> {
        // Simulate the outcome of rolling a die.
        // Either the die will settle, keep rolling, or fall off the table.
        int event = rand() % 6;
        if (event == 0) {
          // The die flew off the table!
          printf("    %s's '%s' die flew right off the table!\n", player.c_str(), type.c_str());
          return fpromise::error();
        }
        if (event < 3) {
          // The die is still rolling around.  Need to wait for it to settle.
          utils::resume_in_a_little_while(context.suspend_task());
          return fpromise::pending();
        }
        // The die has finished rolling, determine how it landed.
        int value = rand() % number_of_sides;
        printf("    %s rolled %d for '%s'\n", player.c_str(), value, type.c_str());
        return fpromise::ok(value);
      });
}

// Re-rolls a die until it succeeds.
//
// This function demonstrates looping a task using a recursive tail-call.
fpromise::promise<int> roll_die_until_successful(std::string player, std::string type,
                                                 int number_of_sides) {
  return roll_die(player, type, number_of_sides).or_else([player, type, number_of_sides] {
    // An error occurred while rolling the die.  Recurse to try again.
    return roll_die_until_successful(player, type, number_of_sides);
  });
}

// Rolls an effect and damage die.
// If the effect die comes up 0 then also rolls an effect multiplier die to
// determine the strength of the effect.  We can do this while waiting
// for the damage die to settle down.
//
// This functions demonstrates the benefits of capturing a task into a
// |fpromise::future| so that its result can be retained and repeatedly
// examined while awaiting other tasks.
auto roll_for_damage(std::string player) {
  return fpromise::make_promise(
      [player, damage = fpromise::future<int>(roll_die_until_successful(player, "damage", 10)),
       effect = fpromise::future<int>(roll_die_until_successful(player, "effect", 4)),
       effect_multiplier =
           fpromise::future<int>()](fpromise::context& context) mutable -> fpromise::result<int> {
        // Evaluate the damage die roll future.
        bool damage_ready = damage(context);

        // Evaluate the effect die roll future.
        // If the player rolled lightning, begin rolling the multiplier.
        bool effect_ready = effect(context);
        if (effect_ready) {
          if (effect.value() == 0) {
            if (!effect_multiplier)
              effect_multiplier = roll_die_until_successful(player, "multiplier", 4);
            effect_ready = effect_multiplier(context);
          }
        }

        // If we're still waiting for the dice to settle, return pending.
        // The task will be resumed once it can make progress.
        if (!effect_ready || !damage_ready)
          return fpromise::pending();

        // Calculate the result and describe what happened.
        if (damage.value() == 0)
          printf("%s swings wildly and completely misses their opponent\n", player.c_str());
        else
          printf("%s hits their opponent for %d damage\n", player.c_str(), damage.value());

        int effect_bonus = 0;
        if (effect.value() == 0) {
          if (effect_bonus == 0) {
            printf(
                "%s attempts to cast 'lightning' but the spell "
                "fizzles without effect\n",
                player.c_str());
          } else {
            effect_bonus = effect_multiplier.value() * 2 + 3;
            printf("%s casts 'lightning' for %d damage\n", player.c_str(), effect_bonus);
          }
        }

        return fpromise::ok(damage.value() + effect_bonus);
      });
}

// Plays one round of the game.
// Both players roll dice simultaneously to determine the damage dealt
// to their opponent.
//
// This function demonstrates joining the results of concurrently executed
// tasks as a new task which produces a tuple.
auto play_round(const std::shared_ptr<game_state>& state) {
  return fpromise::join_promises(roll_for_damage("Red"), roll_for_damage("Blue"))
      .and_then([state](const std::tuple<fpromise::result<int>, fpromise::result<int>>& damages) {
        // Damage tallies are ready, apply them to the game state.
        state->blue_hp = std::max(state->blue_hp - std::get<0>(damages).value(), 0);
        state->red_hp = std::max(state->red_hp - std::get<1>(damages).value(), 0);
        printf("Hit-points remaining: red %d, blue %d\n", state->red_hp, state->blue_hp);
      });
}

// Plays a little game.
// Red and Blue each start with 100 hit points.
// During each round, they both simultaneously roll dice to determine damage to
// their opponent.  If at the end of the round one player's hit-points reaches
// 0, that player loses.  If both players' hit-points reach 0, they both lose.
auto play_game() {
  puts("Red and Blue are playing a game...");
  return fpromise::make_promise(
      [state = std::make_shared<game_state>(),
       round = fpromise::future<>()](fpromise::context& context) mutable -> fpromise::result<> {
        // Repeatedly play rounds until the game ends.
        while (state->red_hp != 0 && state->blue_hp != 0) {
          if (!round)
            round = play_round(state);
          if (!round(context))
            return fpromise::pending();
          round = nullptr;
        }

        // Game over.
        puts("Game over...");
        if (state->red_hp == 0 && state->blue_hp == 0)
          puts("Both players lose!");
        else if (state->red_hp != 0)
          puts("Red wins!");
        else
          puts("Blue wins!");
        return fpromise::ok();
      });
}

void run() { fpromise::run_single_threaded(play_game()); }

}  // namespace promise_example2
