// FilePath: /l:/work/dev/procmanager/src/procmanager.c
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
#include "common_service.h"

#define MAX_PROCESSES 32
#define MONITOR_INTERVAL 5
#define REGISTER_PIPE "/tmp/procmanager_reg"
#define MAX_REGISTER_MSG 512
#define LOCK_TIMEOUT_MS 100

typedef struct {
    char name[64];
    char command[256];
    pid_t pid;
    int restart_count;
    time_t last_start;
    int critical;
    time_t last_heartbeat;
} ManagedProcess;

static ManagedProcess g_processes[MAX_PROCESSES];
static int g_process_count = 0;
static pthread_mutex_t g_proc_mutex = PTHREAD_MUTEX_INITIALIZER;

// 初始化注册管道
static int init_registration_pipe() {
    unlink(REGISTER_PIPE);
    if (mkfifo(REGISTER_PIPE, 0777) < 0) {
        syslog(LOG_ERR, "创建注册管道失败: %s", strerror(errno));
        printf("创建注册管道失败: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}

// 处理单个注册消息
static void process_single_registration(const char *msg) {
    char *saveptr;
    char *name = strtok_r((char*)msg, ":", &saveptr);
    char *pid_str = strtok_r(NULL, ":", &saveptr);
    char *critical_str = strtok_r(NULL, ":", &saveptr);
    
    if (!name || !pid_str || !critical_str) {
        syslog(LOG_WARNING, "无效的注册消息格式: %s", msg);
        printf("无效的注册消息格式: %s", msg);
        return;
    }

    pid_t pid = atoi(pid_str);
    int critical = atoi(critical_str);

    // 验证进程存在
    if (kill(pid, 0) < 0) {
        syslog(LOG_WARNING, "注册失败: 进程 %d 不存在", pid);
        printf("注册失败: 进程 %d 不存在", pid);
        return;
    }

    pthread_mutex_lock(&g_proc_mutex);
    
    // 检查是否已注册
    for (int i = 0; i < g_process_count; i++) {
        if (g_processes[i].pid == pid) {
            pthread_mutex_unlock(&g_proc_mutex);
            syslog(LOG_INFO, "进程已注册: %s [PID:%d]", name, pid);
            printf("进程已注册: %s [PID:%d]", name, pid);
            return;
        }
    }

    // 添加到监控列表
    if (g_process_count < MAX_PROCESSES) {
        ManagedProcess *p = &g_processes[g_process_count++];
        snprintf(p->name, sizeof(p->name), "%s", name);
        
        // 获取进程完整命令
        char cmd_path[256];
        snprintf(cmd_path, sizeof(cmd_path), "/proc/%d/cmdline", pid);
        FILE *fp = fopen(cmd_path, "r");
        if (fp) {
            size_t len = fread(p->command, 1, sizeof(p->command)-1, fp);
            p->command[len] = '\0';
            fclose(fp);
        } else {
            strncpy(p->command, "unknown", sizeof(p->command));
        }
        
        p->pid = pid;
        p->critical = critical;
        p->restart_count = 0;
        p->last_start = time(NULL);
        p->last_heartbeat = time(NULL);
        
        syslog(LOG_INFO, "进程注册成功: %s [PID:%d]", name, pid);
        printf("进程注册成功: %s [PID:%d]", name, pid);
    } else {
        syslog(LOG_ERR, "无法注册进程 %s: 已达最大数量限制", name);
        printf("无法注册进程 %s: 已达最大数量限制", name);
    }
    
    pthread_mutex_unlock(&g_proc_mutex);
}

// 处理注册请求
static void handle_registration() {
    int fd = open(REGISTER_PIPE, O_RDONLY | O_NONBLOCK);
    if (fd < 0) {
        syslog(LOG_ERR, "打开注册管道失败: %s", strerror(errno));
        printf("打开注册管道失败: %s", strerror(errno));
        return;
    }

    char buf[MAX_REGISTER_MSG];
    ssize_t n = read(fd, buf, sizeof(buf)-1);
    close(fd);
    
    if (n <= 0) return;
    buf[n] = '\0';

    // 分割多条消息（每条以\n结尾）
    char *msg = strtok(buf, "\n");
    while (msg) {
        process_single_registration(msg);
        msg = strtok(NULL, "\n");
    }
}

// 检查进程状态
static void check_process_status(ManagedProcess *proc) {
    if (proc->pid <= 0) return;

    // 检查进程是否存在
    if (kill(proc->pid, 0) < 0 && errno == ESRCH) {
        syslog(LOG_WARNING, "进程 %s [PID:%d] 已终止", proc->name, proc->pid);
        if (proc->critical) {
            char alarm_msg[256];
            snprintf(alarm_msg, sizeof(alarm_msg), 
                    "关键进程 %s 异常终止", proc->name);
            //execute_command("alarm_ctl report -n PROCESS_CRASH", 1000, 0, NULL);
        }
        proc->pid = -1;
        return;
    }

    // 检查心跳超时（30秒无心跳认为异常）
    if (difftime(time(NULL), proc->last_heartbeat) > 30) {
        syslog(LOG_WARNING, "进程 %s [PID:%d] 心跳超时", proc->name, proc->pid);
        if (proc->critical) {
            //execute_command("alarm_ctl report -n PROCESS_HANG", 1000, 0, NULL);
        }
        kill(proc->pid, SIGTERM);
        proc->pid = -1;
    }
}

// 主监控循环
void monitor_loop() {
    if (init_registration_pipe() < 0) {
        return;
    }

    while (1) {
        // 处理注册请求
        handle_registration();
        
        // 检查进程状态
        pthread_mutex_lock(&g_proc_mutex);
        for (int i = 0; i < g_process_count; i++) {
            check_process_status(&g_processes[i]);
        }
        pthread_mutex_unlock(&g_proc_mutex);
        
        sleep(MONITOR_INTERVAL);
    }
}

int main() {
    // 启动监控
    monitor_loop();
    return 0;
}
