// SPDX-FileCopyrightText: 2025 UnionTech Software Technology Co., Ltd.
//
// SPDX-License-Identifier: GPL-3.0-or-later

#ifndef SERVICE_H
#define SERVICE_H

#include "systemd/sd-bus.h"
#include "systemd/sd-event.h"

#include <glib.h>

#include <pthread.h>
#include <stdbool.h>
#include <time.h>

/* Forward declaration */
struct err_notify_data;

#ifdef __cplusplus
extern "C" {
#endif

/* D-Bus interface definitions */
#define DBUS_OBJECT_PATH "/org/deepin/immutable/ReadOnlyAuditor1"
#define DBUS_INTERFACE_NAME "org.deepin.immutable.ReadOnlyAuditor1"
#define SYSLOG_IDENTIFIER "deepin-err-notify"

/* Rate limiting configuration */
#define RATE_LIMIT_WINDOW_SECONDS 300 // 5 minutes
#define RATE_LIMIT_MAX_COUNT 1
#define RATE_LIMIT_ENTRY_EXPIRE_SECONDS 310 // 5 min 10 sec (window + buffer)
#define RATE_LIMIT_GC_INTERVAL 100

/* Rate limiting state */
struct rate_limit_state
{
    time_t window_start;
    int count;
    pthread_mutex_t mutex;
};

/* Per-key rate limiting entry */
struct rate_limit_entry
{
    time_t window_start;
    time_t last_access;
    int count;
};

/* Hash table for per-key rate limiting */
struct rate_limit_table
{
    GHashTable *table;
    pthread_mutex_t mutex;
    unsigned int check_count;
};

/* Global state - defined in service.c and plugin.c */
extern sd_bus *g_bus;
extern bool g_enabled;
extern struct rate_limit_state g_rate_limit;
extern struct rate_limit_table g_rate_limit_table;
extern struct err_notify_state *global_state;

/* sd-event related - defined in service.c */
extern sd_event *g_event;
extern sd_event_source *g_netlink_source;
extern pthread_t g_event_thread;

/* Watch directories - defined in service.c */
extern char **g_watch_dirs;
extern size_t g_watch_dirs_count;
extern pthread_mutex_t g_watch_dirs_mutex;

/* Property handlers */
int property_get_enabled(sd_bus *bus,
                         const char *path,
                         const char *interface,
                         const char *property,
                         sd_bus_message *reply,
                         void *userdata,
                         sd_bus_error *ret_error);

int property_set_enabled(sd_bus *bus,
                         const char *path,
                         const char *interface,
                         const char *property,
                         sd_bus_message *value,
                         void *userdata,
                         sd_bus_error *ret_error);

/* Method handlers */
int method_export_log(sd_bus_message *m, void *userdata, sd_bus_error *ret_error);

/* Signal emission */
int emit_error_occurred_signal(const struct err_notify_data *data,
                               const char *cgroup,
                               const char *cmdline);

/* Per-key rate limiting */
void rate_limit_table_init(struct rate_limit_table *table);
bool rate_limit_table_check(struct rate_limit_table *table,
                            const char *cgroup,
                            const char *cmdline);
void rate_limit_table_cleanup(struct rate_limit_table *table);
void rate_limit_table_gc(struct rate_limit_table *table);

/* sd-event loop management */
int event_loop_init(sd_bus *bus, struct err_notify_state *netlink_state);
void event_loop_cleanup(void);

#ifdef __cplusplus
}
#endif

#endif // SERVICE_H
