#pragma once

#include <string>
#include <filesystem>

struct lua_State;

namespace mosis {

class PathSandbox {
public:
    explicit PathSandbox(const std::string& app_path);

    // Validate a path is within the sandbox
    // Returns true if valid, sets out_canonical to the resolved path
    bool ValidatePath(const std::string& path, std::string& out_canonical);

    // Check if path contains traversal attempts (..)
    static bool ContainsTraversal(const std::string& path);

    // Check if path is absolute
    static bool IsAbsolutePath(const std::string& path);

    // Normalize path separators and remove redundant ./ components
    static std::string NormalizePath(const std::string& path);

    // Validate module name for require() - alphanumeric, underscore, dots only
    static bool IsValidModuleName(const std::string& name);

    // Convert module name to relative path (e.g., "ui.button" -> "scripts/ui/button.lua")
    static std::string ModuleToPath(const std::string& module_name);

    // Get the app's base path
    const std::string& GetAppPath() const { return m_app_path; }

    // Resolve a relative path to full path within sandbox
    std::string ResolvePath(const std::string& relative_path);

private:
    std::string m_app_path;
};

// Safe require implementation for Lua
// Loads modules only from app_path/scripts/<module>.lua
// Caches modules in registry
int SafeRequire(lua_State* L);

// Register safe require as global "require"
// The PathSandbox pointer is stored in registry for use by SafeRequire
void RegisterSafeRequire(lua_State* L, PathSandbox* sandbox);

} // namespace mosis
