#pragma once

#include <string>
#include <vector>
#include <mutex>
#include <chrono>

namespace mosis {

enum class AuditEvent {
    // Lifecycle
    AppStart,
    AppStop,

    // Permissions
    PermissionCheck,
    PermissionGranted,
    PermissionDenied,

    // Network
    NetworkRequest,
    NetworkBlocked,

    // Storage
    FileAccess,
    FileBlocked,
    DatabaseAccess,

    // Hardware
    CameraAccess,
    MicrophoneAccess,
    LocationAccess,

    // Security
    SandboxViolation,
    ResourceLimitHit,
    RateLimitHit,

    // Other
    Custom
};

struct AuditEntry {
    std::chrono::system_clock::time_point timestamp;
    AuditEvent event;
    std::string app_id;
    std::string details;
    bool success;
};

class AuditLog {
public:
    explicit AuditLog(size_t max_entries = 10000);

    // Log an event
    void Log(AuditEvent event, const std::string& app_id,
             const std::string& details = "", bool success = true);

    // Query entries (returns most recent first)
    std::vector<AuditEntry> GetEntries(size_t count = 100) const;
    std::vector<AuditEntry> GetEntriesForApp(const std::string& app_id,
                                              size_t count = 100) const;
    std::vector<AuditEntry> GetEntriesByEvent(AuditEvent event,
                                               size_t count = 100) const;

    // Statistics
    size_t GetTotalEntries() const;
    size_t GetStoredEntries() const;
    size_t CountEvents(AuditEvent event, const std::string& app_id = "") const;

    // Clear all entries
    void Clear();

    // Convert event to string for logging
    static const char* EventToString(AuditEvent event);

private:
    mutable std::mutex m_mutex;
    std::vector<AuditEntry> m_entries;
    size_t m_max_entries;
    size_t m_write_index = 0;
    size_t m_total_logged = 0;
    bool m_wrapped = false;
};

// Global audit log (singleton)
AuditLog& GetAuditLog();

} // namespace mosis

// Convenience alias
using AuditLog = mosis::AuditLog;
using AuditEvent = mosis::AuditEvent;
using AuditEntry = mosis::AuditEntry;
