// ============================================================================
// LUA GAME LOADER - EMULATOR IMPLEMENTATION
// ============================================================================
// Discovers Lua scripts from filesystem and integrates with game launcher

#include "../games/lua_game_loader.h"
#include "../games/lua_game.h"
#include <stdio.h>
#include <string.h>
#include <vector>
#include <fstream>
#include <sstream>
#include <filesystem>
#include <iostream>

namespace fs = std::filesystem;

// Structure to hold script path for factory closure
struct LuaGameFactoryData {
    char script_path[256];
    char name[64];
    char description[128];
};

static std::vector<LuaGameFactoryData*> factory_data_list;

bool LuaGameLoader::parse_metadata(const char* script_path, char* name, char* description) {
    // Default name from filename
    fs::path path(script_path);
    std::string filename = path.stem().string();  // Get filename without extension
    strncpy(name, filename.c_str(), 63);
    name[63] = '\0';
    
    // Default empty description
    description[0] = '\0';
    
    // Try to open file and parse metadata comments
    std::ifstream file(script_path);
    if (!file.is_open()) {
        printf("LuaGameLoader: Warning - could not open %s for metadata\n", script_path);
        return false;
    }
    
    // Read first 512 bytes to look for metadata comments
    char buffer[512];
    file.read(buffer, sizeof(buffer) - 1);
    std::streamsize bytes_read = file.gcount();
    file.close();
    
    if (bytes_read == 0) {
        return false;
    }
    
    buffer[bytes_read] = '\0';
    
    // Parse metadata comments: -- NAME: Game Name
    char* line = buffer;
    while (line && (line - buffer) < bytes_read) {
        char* next_line = strchr(line, '\n');
        if (next_line) *next_line = '\0';
        
        // Check for -- NAME: 
        if (strncmp(line, "-- NAME:", 8) == 0) {
            const char* value = line + 8;
            while (*value == ' ') value++;  // Skip spaces
            strncpy(name, value, 63);
            name[63] = '\0';
        }
        // Check for -- DESC:
        else if (strncmp(line, "-- DESC:", 8) == 0) {
            const char* value = line + 8;
            while (*value == ' ') value++;
            strncpy(description, value, 127);
            description[127] = '\0';
        }
        
        if (next_line) {
            line = next_line + 1;
        } else {
            break;
        }
    }
    
    return true;
}

int LuaGameLoader::register_all_games(GameLauncher* launcher) {
    int count = 0;
    
    printf("LuaGameLoader: Scanning games/lua_examples directory for .lua scripts...\n");
    
    // Path to lua examples relative to emulator binary
    const char* search_paths[] = {
        "../games/lua_examples",
        "games/lua_examples",
        "./lua_examples"
    };
    
    fs::path games_dir;
    bool found_dir = false;
    
    // Try to find the lua_examples directory
    for (const char* search_path : search_paths) {
        if (fs::exists(search_path) && fs::is_directory(search_path)) {
            games_dir = fs::path(search_path);
            found_dir = true;
            break;
        }
    }
    
    if (!found_dir) {
        printf("LuaGameLoader: Could not find games/lua_examples directory\n");
        printf("LuaGameLoader: Tried: ../games/lua_examples, games/lua_examples, ./lua_examples\n");
        return 0;
    }
    
    printf("LuaGameLoader: Found directory: %s\n", games_dir.string().c_str());
    
    // Scan for .lua files
    try {
        for (const auto& entry : fs::directory_iterator(games_dir)) {
            if (!entry.is_regular_file()) continue;
            
            // Check for .lua extension
            if (entry.path().extension() != ".lua") continue;
            
            std::string script_path = entry.path().string();
            
            // Create factory data (persistent for game lifetime)
            LuaGameFactoryData* data = new LuaGameFactoryData();
            strncpy(data->script_path, script_path.c_str(), sizeof(data->script_path) - 1);
            data->script_path[sizeof(data->script_path) - 1] = '\0';
            
            // Parse metadata directly into persistent storage
            parse_metadata(script_path.c_str(), data->name, data->description);
            
            printf("LuaGameLoader: Found %s - '%s'\n", entry.path().filename().string().c_str(), data->name);
            
            factory_data_list.push_back(data);
            
            // Register with launcher - using lambda factory pattern
            launcher->register_game(
                data->name,
                data->description[0] ? data->description : "Lua Script",
                [data](uint16_t width, uint16_t height, LowLevelRenderer* renderer, 
                       LowLevelGUI* gui, InputManager* input_manager) -> Game* {
                    return new LuaGame(data->script_path, width, height, renderer, gui, input_manager);
                }
            );
            
            count++;
        }
    } catch (const fs::filesystem_error& e) {
        printf("LuaGameLoader: Error scanning directory: %s\n", e.what());
        return count;
    }
    
    printf("LuaGameLoader: Registered %d Lua games\n", count);
    return count;
}
