#include <iomanip>
#include <iostream>
#include <string>

#include <opencv2/core.hpp>

#include "OpenMVS/MVS/Interface.h"

// Minimal JSON string escape for paths/messages.
static std::string json_escape(const std::string& s) {
    std::string out;
    out.reserve(s.size());
    for (char c : s) {
        if (c == '\\' || c == '"') {
            out.push_back('\\');
        }
        out.push_back(c);
    }
    return out;
}

static void emit_json(
    int error_code,
    int schema_version,
    std::size_t point_count,
    const float minv[3],
    const float maxv[3],
    const std::string& message
) {
    std::cout << std::fixed << std::setprecision(6)
              << "{"
              << "\"schema_magic\":\"MVSI\","
              << "\"tool\":\"RL_BRIDGE_PROBE\","
              << "\"schema_version\":" << schema_version << ","
              << "\"error_code\":" << error_code << ","
              << "\"point_count\":" << point_count << ","
              << "\"aabb_min\":[" << minv[0] << "," << minv[1] << "," << minv[2] << "],"
              << "\"aabb_max\":[" << maxv[0] << "," << maxv[1] << "," << maxv[2] << "],"
              << "\"message\":\"" << json_escape(message) << "\""
              << "}" << std::endl;
}

int main(int argc, char* argv[]) {
    std::string input_path;
    for (int i = 1; i < argc; ++i) {
        const std::string arg(argv[i]);
        if (arg == "--input" && (i + 1) < argc) {
            input_path = argv[++i]; // consume value
        }
    }

    float zero[3] = {0.0f, 0.0f, 0.0f};
    if (input_path.empty()) {
        emit_json(1, 0, 0, zero, zero, "Missing --input");
        return 1;
    }

    MVS::Interface interface;
    uint32_t loaded_version = 0;
    if (!MVS::ARCHIVE::SerializeLoad(interface, input_path, &loaded_version)) {
        emit_json(2, 0, 0, zero, zero, "ARCHIVE Load failed");
        return 2;
    }

    const std::size_t count = interface.vertices.size();

    float minv[3] = {0.0f, 0.0f, 0.0f};
    float maxv[3] = {0.0f, 0.0f, 0.0f};
    if (count > 0) {
        minv[0] = maxv[0] = interface.vertices[0].X.x;
        minv[1] = maxv[1] = interface.vertices[0].X.y;
        minv[2] = maxv[2] = interface.vertices[0].X.z;
        for (std::size_t i = 1; i < count; ++i) {
            const auto& p = interface.vertices[i].X;
            if (p.x < minv[0]) minv[0] = p.x;
            if (p.y < minv[1]) minv[1] = p.y;
            if (p.z < minv[2]) minv[2] = p.z;
            if (p.x > maxv[0]) maxv[0] = p.x;
            if (p.y > maxv[1]) maxv[1] = p.y;
            if (p.z > maxv[2]) maxv[2] = p.z;
        }
    }

    emit_json(0, static_cast<int>(loaded_version), count, minv, maxv, "");
    return 0;
}
