//
// Created by Dan Crosby on 4/16/22.
//

#include "MapInfoCalculator.hpp"

#include "src/main/cpp/net/eagle0/shardok/ai/AIWaterCrossingCalculator.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/fb_helpers/HexMapHelpers.hpp"
#include "src/main/cpp/net/eagle0/shardok/library/util/HexMapUtils.hpp"
#include "src/main/cpp/net/eagle0/shardok/util/MapLoader.hpp"

using namespace shardok;
using std::endl;

auto LoadMapFb(const string& mapName) -> Wrapper<HexMap> {
    const HexMapProto mapProto = LoadMap(mapName);

    flatbuffers::FlatBufferBuilder fbb{};
    const auto hexMapOffset = fb::ConvertHexMapProto(fbb, mapProto);
    fbb.Finish(hexMapOffset);
    return Wrapper<HexMap>(fbb);
}

auto CalculateMap(
        const string& mapName,
        const std::shared_ptr<ActionPointDistancesCache>& apdCache,
        const BattalionTypeSPtr& battalionType) -> OneMapInfo {
    auto hexMap = LoadMapFb(mapName);

    const auto mapId = ActionPointDistancesCache::GetMapId(hexMap);

    const CoordsSet criticalTileLocations = GetCriticalTileLocations(hexMap);

    OneMapInfo info{
            .castleCount = criticalTileLocations.size(),
            .name = mapName,
            .positionsRequiringCrossing = {}};

    for (int i = 0; i < hexMap->attacker_starting_positions()->size(); i++) {
        const auto* positionList = hexMap->attacker_starting_positions()->Get(i);
        if (positionList->positions()->size() < 1) continue;
        if (positionList->positions()->size() != 10) {
            printf("Should have 10 starting positions!");
            abort();
        }

        int positionsRequiringCrossing = 0;
        for (const auto* startingPosition : *positionList->positions()) {
            for (const Coords& castlePosition : criticalTileLocations) {
                if (!CanReach(
                            *startingPosition,
                            castlePosition,
                            hexMap,
                            mapId,
                            apdCache,
                            battalionType)) {
                    ++positionsRequiringCrossing;
                    break;
                };
            }
        }
        info.positionsRequiringCrossing[i] = positionsRequiringCrossing;
    }

    return info;
}