#pragma once

#include <string>
#include <vector>
#include <unordered_set>
#include <unordered_map>
#include <chrono>

struct lua_State;

namespace mosis {

struct SandboxContext;  // Forward declaration

enum class PermissionCategory {
    Normal,     // Auto-granted when declared (e.g., internet, vibrate)
    Dangerous,  // Requires user consent (e.g., camera, location)
    Signature   // System apps only (e.g., system.settings)
};

struct PermissionInfo {
    PermissionCategory category;
    std::string description;
};

class PermissionGate {
public:
    explicit PermissionGate(const SandboxContext& context);

    // Check if app has permission (throws Lua error if not)
    bool Check(lua_State* L, const std::string& permission);

    // Check without throwing (returns false if denied)
    bool HasPermission(const std::string& permission) const;

    // Get permission category
    static PermissionCategory GetCategory(const std::string& permission);

    // Get permission info (returns nullptr if unknown)
    static const PermissionInfo* GetPermissionInfo(const std::string& permission);

    // User gesture tracking
    void RecordUserGesture();
    bool HasRecentUserGesture(int ms = 5000) const;

    // Runtime permission grant (called after user consent)
    void GrantPermission(const std::string& permission);
    void RevokePermission(const std::string& permission);

    // Get all declared permissions
    const std::vector<std::string>& GetDeclaredPermissions() const;

    // Get all granted permissions
    std::vector<std::string> GetGrantedPermissions() const;

    // Check if permission is declared in manifest
    bool IsDeclared(const std::string& permission) const;

private:
    const SandboxContext& m_context;
    std::unordered_set<std::string> m_runtime_grants;  // Runtime-granted dangerous perms
    std::chrono::steady_clock::time_point m_last_gesture;

    bool CheckNormalPermission(const std::string& permission) const;
    bool CheckDangerousPermission(const std::string& permission) const;
    bool CheckSignaturePermission(const std::string& permission) const;
};

} // namespace mosis

// Convenience alias
using PermissionGate = mosis::PermissionGate;
using PermissionCategory = mosis::PermissionCategory;
