// D:\Dev\Mosis\MosisService\designer\src\app_discovery.cpp
#include "app_discovery.h"
#include <nlohmann/json.hpp>
#include <filesystem>
#include <fstream>
#include <iostream>

namespace fs = std::filesystem;
using json = nlohmann::json;

namespace mosis {

std::vector<AppInfo> AppDiscovery::DiscoverApps(const std::string& apps_directory) {
    std::vector<AppInfo> apps;

    if (!fs::exists(apps_directory) || !fs::is_directory(apps_directory)) {
        std::cerr << "AppDiscovery: Directory not found: " << apps_directory << std::endl;
        return apps;
    }

    std::cout << "AppDiscovery: Scanning " << apps_directory << std::endl;

    for (const auto& entry : fs::directory_iterator(apps_directory)) {
        if (!entry.is_directory()) continue;

        std::string app_dir = entry.path().string();
        AppInfo info;

        if (LoadAppManifest(app_dir, info)) {
            apps.push_back(std::move(info));
            std::cout << "AppDiscovery: Found app '" << apps.back().name
                      << "' (" << apps.back().id << ")" << std::endl;
        }
    }

    std::cout << "AppDiscovery: Found " << apps.size() << " apps" << std::endl;
    return apps;
}

bool AppDiscovery::LoadAppManifest(const std::string& app_directory, AppInfo& info) {
    fs::path manifest_path = fs::path(app_directory) / "manifest.json";

    if (!fs::exists(manifest_path)) {
        return false;
    }

    try {
        std::ifstream file(manifest_path);
        if (!file.is_open()) {
            std::cerr << "AppDiscovery: Cannot open " << manifest_path << std::endl;
            return false;
        }

        json j;
        file >> j;

        // Required fields
        if (!j.contains("id") || !j.contains("name") || !j.contains("entry")) {
            std::cerr << "AppDiscovery: Missing required fields in " << manifest_path << std::endl;
            return false;
        }

        info.id = j["id"].get<std::string>();
        info.name = j["name"].get<std::string>();
        info.entry = j["entry"].get<std::string>();

        // Optional fields
        info.version = j.value("version", "1.0.0");
        info.icon = j.value("icon", "icon.tga");
        info.description = j.value("description", "");
        info.is_system_app = j.value("is_system_app", false);

        // Normalize path separators
        info.app_path = app_directory;
        std::replace(info.app_path.begin(), info.app_path.end(), '\\', '/');

        // Verify entry file exists
        fs::path entry_path = fs::path(app_directory) / info.entry;
        if (!fs::exists(entry_path)) {
            std::cerr << "AppDiscovery: Entry file not found: " << entry_path << std::endl;
            return false;
        }

        return true;
    }
    catch (const std::exception& e) {
        std::cerr << "AppDiscovery: Error parsing " << manifest_path << ": " << e.what() << std::endl;
        return false;
    }
}

} // namespace mosis
