//
// Created by Dan Crosby on 3/5/21.
//

#include "FortifyCommandFactory.hpp"

#include "src/main/cpp/net/eagle0/shardok/library/commands/FortifyCommand.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/unit/Unit.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/util/HexMapUtils.hpp"

namespace shardok {

auto FortifyCommandFactory::AddAvailableFortifyCommands(
        CommandList& existingCommands,
        const Unit* actor,
        const ActionPoints remainingActionPoints,
        const Terrain* terrain) const -> void {
    // Must have a hero and it must be an engineer
    if (!actor->has_attached_hero()) return;
    if (actor->attached_hero().profession_info().profession() !=
        net::eagle0::shardok::storage::fb::Profession_ENGINEER)
        return;

    // Must not already be fortified
    if (actor->fortified()) return;

    // Must be fortifiable terrain
    if (!AllowsFortification(terrain)) return;

    // Must have enough action points
    ActionCost cost = ActionCost::UsesAllActionCost(settings.Backing().fortify_action_point_cost());
    if (!cost.IsPossible(remainingActionPoints)) return;

    existingCommands.emplace_back(std::make_shared<FortifyCommand>(
            cost,
            actor->player_id(),
            actor->unit_id(),
            settings.Backing().fortify_strength_xp(),
            settings.Backing().fortify_agility_xp(),
            settings.Backing().minimum_knowledge_for_profession()));
}

void FortifyCommandFactory::AddAvailableCommands(CommandList& commands, const CommandParams& params)
        const {
    AddAvailableFortifyCommands(
            commands,
            params.unit,
            params.remainingActionPoints,
            GetTerrain(params.hexMap, params.position));
}

}  // namespace shardok
