#pragma once

#include <string>
#include <vector>
#include <cstdint>
#include <optional>
#include <functional>

struct lua_State;

namespace mosis {

struct FileStat {
    size_t size;
    int64_t modified;  // Unix timestamp
    bool is_dir;
};

struct VirtualFSLimits {
    size_t max_quota_bytes = 50 * 1024 * 1024;      // 50 MB per app
    size_t max_file_size = 10 * 1024 * 1024;        // 10 MB per file
    int max_path_depth = 10;                         // Max directory depth
    size_t max_path_length = 256;                    // Max path string length
};

class VirtualFS {
public:
    VirtualFS(const std::string& app_id,
              const std::string& app_root,
              const VirtualFSLimits& limits = VirtualFSLimits{});
    ~VirtualFS();

    // Path operations
    bool ValidatePath(const std::string& virtual_path, std::string& error);
    std::string ResolvePath(const std::string& virtual_path);

    // File operations
    std::optional<std::string> Read(const std::string& path, std::string& error);
    bool Write(const std::string& path, const std::string& data, std::string& error);
    bool Append(const std::string& path, const std::string& data, std::string& error);
    bool Delete(const std::string& path, std::string& error);
    bool Exists(const std::string& path);
    std::optional<std::vector<std::string>> List(const std::string& path, std::string& error);
    bool MakeDir(const std::string& path, std::string& error);
    std::optional<FileStat> Stat(const std::string& path, std::string& error);

    // Quota management
    size_t GetUsedBytes() const { return m_used_bytes; }
    size_t GetQuotaBytes() const { return m_limits.max_quota_bytes; }
    void RecalculateUsage();

    // Cleanup
    void ClearTemp();
    void ClearAll();  // For testing

    // Permission check callback (set by sandbox)
    std::function<bool(const std::string&)> CheckPermission;

private:
    std::string m_app_id;
    std::string m_app_root;
    VirtualFSLimits m_limits;
    size_t m_used_bytes = 0;

    bool EnsureParentDir(const std::string& path);
    void UpdateUsage(int64_t delta);
    bool CheckQuota(size_t additional_bytes, std::string& error);
    int GetPathDepth(const std::string& path);
    bool IsValidPathChar(char c);
    void DeleteDirectoryRecursive(const std::string& path);
    size_t CalculateDirectorySize(const std::string& path);
};

// Register fs.* APIs as globals
void RegisterVirtualFS(lua_State* L, VirtualFS* vfs);

} // namespace mosis
