//
// Created by Dan Crosby on 11/25/20.
//

#include "EndPlayerSetupCommand.hpp"

#include "src/main/cpp/net/eagle0/shardok/library/action_result_applier/ActionResultApplier.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/actions/NewRoundAction.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/actions/StartPlayerTurnAction.hpp"

namespace shardok {

using net::eagle0::shardok::common::ActionType;
using net::eagle0::shardok::common::GameStatus;

auto EndPlayerSetupCommand::InternalExecute(
        const GameStateW& currentState,
        const std::shared_ptr<RandomGenerator>& generator) const -> vector<ActionResultProto> {
    auto startingGameState = gameState;

    ActionResultProto endResult{};
    endResult.set_type(ActionType::PLAYER_SETUP_ENDED);
    endResult.mutable_player()->set_value(GetPlayerId());
    endResult.mutable_next_player()->set_value(nextPid);

    vector<ActionResultProto> allResults = {endResult};

    if (nextPid == 0) {
        startingGameState = ApplyResult(startingGameState, endResult, settings);

        ActionResultProto gameStartResult{};
        gameStartResult.set_type(ActionType::GAME_START);
        gameStartResult.mutable_game_status()->set_state(
                GameStatus::State::GameStatus_State_GAME_RUNNING);
        gameStartResult.mutable_game_status()->set_description("The game has begun!");
        allResults.push_back(gameStartResult);

        startingGameState = ApplyResult(startingGameState, gameStartResult, settings);

        auto newRoundResults =
                NewRoundAction(startingGameState, settings).Execute(currentState, generator);
        startingGameState = ApplyResults(startingGameState, newRoundResults, settings);

        allResults.insert(allResults.end(), newRoundResults.begin(), newRoundResults.end());

        auto startTurnResults =
                StartPlayerTurnAction(gameState, startingGameState->current_player(), settings)
                        .Execute(currentState, generator);
        allResults.insert(allResults.end(), startTurnResults.begin(), startTurnResults.end());
    }

    return allResults;
}

auto EndPlayerSetupCommand::GetCommandProto() const -> shardok::CommandProto {
    CommandProto proto{};

    proto.set_player(GetPlayerId());
    proto.set_type(net::eagle0::shardok::common::END_PLAYER_SETUP_COMMAND);

    return proto;
}

}  // namespace shardok