// message_bus.h - Inter-app message bus for Lua sandbox
// Milestone 18: Kernel-mediated message passing between apps
#pragma once

#include <string>
#include <vector>
#include <functional>
#include <mutex>
#include <unordered_map>
#include <unordered_set>

struct lua_State;

namespace mosis {

struct Intent {
    std::string action;      // Intent action (e.g., "share", "view", "edit")
    std::string type;        // MIME type (e.g., "text/plain", "image/png")
    std::string data;        // Intent data/payload
    std::string from_app;    // Sender app ID (set by kernel)
};

struct IntentFilter {
    std::string action;                   // Required action
    std::vector<std::string> types;       // Accepted MIME types (empty = all)
};

enum class MessageError {
    None,
    NoReceivers,
    PermissionDenied,
    InvalidIntent,
    DataTooLarge,
    ReceiverNotFound,
    SenderBlocked
};

class MessageBus {
public:
    using IntentHandler = std::function<void(const Intent&)>;

    MessageBus();
    ~MessageBus();

    // Register an app to receive intents
    void RegisterReceiver(
        const std::string& app_id,
        const IntentFilter& filter,
        IntentHandler handler
    );

    // Unregister all handlers for an app
    void UnregisterApp(const std::string& app_id);

    // Send intent to specific app (requires permission)
    MessageError Send(
        const std::string& sender_app,
        const std::string& target_app,
        const Intent& intent,
        std::string& error
    );

    // Broadcast intent to all registered receivers
    MessageError Broadcast(
        const std::string& sender_app,
        const Intent& intent,
        std::string& error
    );

    // Check if any app handles this action
    bool HasReceiverFor(const std::string& action) const;

    // Get list of apps that handle an action
    std::vector<std::string> GetReceiversFor(const std::string& action) const;

    // Permission management
    void SetAppPermission(const std::string& app_id, const std::string& permission, bool granted);
    bool HasPermission(const std::string& app_id, const std::string& permission) const;

    // Block specific app from sending/receiving
    void BlockApp(const std::string& app_id);
    void UnblockApp(const std::string& app_id);
    bool IsBlocked(const std::string& app_id) const;

    // Clear all registrations (for testing)
    void Clear();

    // Statistics
    size_t GetReceiverCount() const;
    size_t GetMessageCount() const { return m_message_count; }

private:
    struct ReceiverEntry {
        std::string app_id;
        IntentFilter filter;
        IntentHandler handler;
    };

    std::vector<ReceiverEntry> m_receivers;
    std::unordered_map<std::string, std::unordered_set<std::string>> m_permissions;
    std::unordered_set<std::string> m_blocked_apps;
    mutable std::mutex m_mutex;
    size_t m_message_count = 0;

    static constexpr size_t MAX_DATA_SIZE = 1024 * 1024;  // 1MB max

    bool MatchesFilter(const Intent& intent, const IntentFilter& filter) const;
    bool ValidateIntent(const Intent& intent, std::string& error) const;
};

// Register intents.* APIs as globals
void RegisterIntentsAPI(lua_State* L, MessageBus* bus, const std::string& app_id);

} // namespace mosis
