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

#include "UndeadChangeAction.hpp"

#include <algorithm>

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

namespace shardok {

auto UndeadChangeAction::InternalExecute(
        const GameStateW& currentState,
        const std::shared_ptr<RandomGenerator>& generator) const -> vector<ActionResult> {
    if (undeadUnitIds.empty()) return {};

    const int maxGrowthPer = (int)(reinforceRate * bodyCount / (double)undeadUnitIds.size());

    ActionResult result{};
    result.set_type(net::eagle0::shardok::common::UNDEAD_GREW);
    for (const UnitId unitId : undeadUnitIds) {
        const auto* unit = currentState->units()->Get(unitId);

        int startSize = unit->battalion().size();
        int decayedSize = startSize;

        if (startSize > decayFloor) {
            decayedSize = decayFloor + (startSize - decayFloor) * (1.0 - decayRate);
        }

        int newCount = std::min(decayedSize + maxGrowthPer, undeadCapacity);
        int growth = newCount - decayedSize;

        float newArmament =
                float(unit->battalion().armament() * decayedSize + armament * growth) / newCount;

        auto newUnit = *unit;
        newUnit.mutable_battalion().mutate_size(newCount);
        newUnit.mutable_battalion().mutate_armament(newArmament);

        AddChangedUnit(result, newUnit);
    }

    return {result};
}
}  // namespace shardok
