//
//  EvacuatePrisonersCommand.cpp
//  eagle0
//

#include "EvacuatePrisonersCommand.hpp"

#include <utility>

#include "src/main/cpp/net/eagle0/shardok/library/util/ActionResultFlatbufferHelpers.hpp"

namespace shardok {

auto EvacuatePrisonersCommand::InternalExecute(
        const GameStateW& currentState,
        const std::shared_ptr<RandomGenerator>& /*generator*/) const -> vector<ActionResult> {
    ActionResult result{};
    result.mutable_player()->set_value(GetPlayerId());
    result.mutable_actor()->set_value(actorId);
    result.set_type(net::eagle0::shardok::common::ActionType::EVACUATED_PRISONERS);

    const auto* actorUnit = currentState->units()->Get(actorId);
    auto* resolvedActor = result.add_resolved_units();
    AddUnitToResolved(*resolvedActor, *actorUnit);
    resolvedActor->set_status(
            net::eagle0::shardok::storage::ResolvedUnit_UnitStatus_EVACUATED_UNIT);

    for (const auto captiveUnitId : captiveUnitIds) {
        const auto* captiveUnit = currentState->units()->Get(captiveUnitId);
        auto* resolvedCaptive = result.add_resolved_units();
        AddUnitToResolved(*resolvedCaptive, *captiveUnit);
        resolvedCaptive->set_status(
                net::eagle0::shardok::storage::ResolvedUnit_UnitStatus_SECURED_UNIT);
        resolvedCaptive->mutable_secured_by_player()->set_value(GetPlayerId());
    }

    return {result};
}

EvacuatePrisonersCommand::EvacuatePrisonersCommand(
        const ActionCost& cost,
        const PlayerId playerId,
        const UnitId actorId,
        std::vector<UnitId> captiveUnitIds)
    : ShardokCommand(playerId),
      cost(cost),
      actorId(actorId),
      captiveUnitIds(std::move(captiveUnitIds)) {}

auto EvacuatePrisonersCommand::GetCommandProto() const -> CommandProto {
    CommandProto proto;

    proto.set_player(GetPlayerId());
    proto.set_type(net::eagle0::shardok::common::EVACUATE_PRISONERS_COMMAND);
    proto.mutable_actor()->set_value(actorId);

    return proto;
}
}  // namespace shardok
