//
// Created by Dan Crosby on 6/30/20.
//

#include "ReleaseUnitCommand.hpp"

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

namespace shardok {

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

    proto.set_player(GetPlayerId());
    proto.set_type(net::eagle0::shardok::common::RELEASE_UNIT_COMMAND);
    proto.mutable_actor()->set_value(actingUnitId);
    proto.mutable_target_unit()->set_value(releasedUnitId);

    return proto;
}

auto ReleaseUnitCommand::InternalExecute(
        const GameStateW& currentState,
        const std::shared_ptr<RandomGenerator>& generator) const -> vector<ActionResult> {
    auto controllingUnitAfter = *currentState->units()->Get(actingUnitId);
    controllingUnitAfter.mutate_remaining_action_points(0);
    controllingUnitAfter.mutable_attached_hero().mutable_control_info().mutate_controlled_unit_id(
            -1);

    auto releasedUnitAfter = *currentState->units()->Get(releasedUnitId);
    releasedUnitAfter.mutate_commanding_unit_id(-1);
    releasedUnitAfter.mutate_remaining_action_points(0);

    ActionResult result{};
    result.set_type(net::eagle0::shardok::common::RELEASED_UNIT);
    result.mutable_player()->set_value(GetPlayerId());
    result.mutable_actor()->set_value(actingUnitId);
    result.mutable_target_unit()->set_value(releasedUnitId);
    AddChangedUnit(result, controllingUnitAfter);

    releasedUnitAfter.mutate_player_id(UNCONTROLLED_PLAYER_ID);
    releasedUnitAfter.mutate_targeted_unit(controllingUnitAfter.unit_id());
    AddChangedUnit(result, releasedUnitAfter);

    return {result};
}

}  // namespace shardok