//
// Created by Dan Crosby on 3/19/20.
//

#include <iostream>

#include "src/main/cpp/net/eagle0/common/FilesystemUtils.hpp"
#include "src/main/cpp/net/eagle0/common/byte_vector.hpp"
#include "src/main/protobuf/net/eagle0/shardok/common/hex_map.pb.h"

using HexMapProto = net::eagle0::shardok::common::HexMap;

void ModifyMap(HexMapProto& map);

int main(const int argc, char** argv) {
    if (argc < 3) {
        std::cerr << "Usage: " << argv[0] << " input_path output_path\n";
        return -1;
    }

    const std::string inputPath = argv[1];
    const std::string outputPath = argv[2];
    const byte_vector mapProtoBytes = byte_vector::FromPath(inputPath);
    net::eagle0::shardok::common::HexMap mapProto;
    if (!mapProto.ParseFromArray(mapProtoBytes.data(), static_cast<int>(mapProtoBytes.size()))) {
        std::cerr << "Failed to parse hex map from " << inputPath << '\n';
        return -1;
    }

    ModifyMap(mapProto);
    const std::string outputString = mapProto.SerializeAsString();
    if (FilesystemUtils::AtomicallySaveToPath(outputPath, byte_vector(outputString))) return 0;

    std::cerr << "Failed to save.\n";
    return -1;
}

void ModifyMap(HexMapProto& map) {
    const int terrainCount = map.terrain_size();
    for (int i = 0; i < terrainCount; ++i) {
        const auto existingTerrainType = map.terrain(i).type();
        const auto newTerrain =
                static_cast<net::eagle0::shardok::common::Terrain_Type>(existingTerrainType + 2);
        map.mutable_terrain(i)->set_type(newTerrain);
    }
}
