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

#include "MeteorTargetCommand.hpp"

#include <utility>

#include "src/main/cpp/net/eagle0/shardok/library/actions/ActionRequiresHeroException.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/unit/Unit.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/util/ActionResultFlatbufferHelpers.hpp"

namespace shardok {

auto shardok::MeteorTargetCommand::InternalExecute(
        const GameStateW &currentState,
        const std::shared_ptr<RandomGenerator> &generator) const -> vector<ActionResult> {
    const Unit *caster = currentState->units()->Get(casterId);
    auto casterAfter = *caster;

    MutatingSpendActionPoints(&casterAfter, cost);
    MutatingBumpAllKnowledgeToMinimum(&casterAfter, minimumKnowledge);
    auto &mutableHero = casterAfter.mutable_attached_hero();

    mutableHero.mutable_profession_info().mutable_cast_target() = target;

    ActionResult result{};
    result.set_type(net::eagle0::shardok::common::METEOR_TARGET);
    result.mutable_player()->set_value(GetPlayerId());
    result.mutable_actor()->set_value(casterId);
    *result.mutable_target_coords() = ToCoordsProto(target);

    AddChangedUnit(result, casterAfter);

    return {result};
}

MeteorTargetCommand::MeteorTargetCommand(
        const ActionCost &cost,
        const SettingsGetter &settingsGetter,
        const PlayerId playerId,
        const UnitId casterId,
        Coords target,
        const int minimumKnowledge)
    : ShardokCommand(playerId),
      cost(cost),
      settings(settingsGetter),
      casterId(casterId),
      target(std::move(target)),
      minimumKnowledge(minimumKnowledge) {}

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

    proto.set_player(GetPlayerId());
    proto.set_type(net::eagle0::shardok::common::METEOR_TARGET_COMMAND);
    proto.mutable_actor()->set_value(casterId);
    *proto.mutable_target() = ToCoordsProto(target);

    return proto;
}

}  // namespace shardok
