#include <syslog.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <systemd/sd-bus.h>
#include <unistd.h>
#include <fcntl.h>
#include <dbus/dbus.h>
#include <dbus/dbus-glib-lowlevel.h> /* for glib main loop */

pthread_t file_tid;
// static int inhibit(sd_bus* bus, const char* what) {
//         sd_bus_message* reply = NULL;
//         sd_bus_error error = SD_BUS_ERROR_NULL;
//         const char* who = "ostree-restore", * reason = "Just because!", * mode = "block";
//         int fd;
//         int r;

//         r = sd_bus_call_method(bus,
//                 "org.freedesktop.login1",
//                 "/org/freedesktop/login1",
//                 "org.freedesktop.login1.Manager",
//                 "Inhibit",
//                 &error,
//                 &reply,
//                 "ssss", what, who, reason, mode);

//         r = sd_bus_message_read_basic(reply, SD_BUS_TYPE_UNIX_FD, &fd);
//         syslog(LOG_INFO,"xxxxxxxxxxxxfd = %d\n", fd);
//         return fcntl(fd, F_DUPFD_CLOEXEC, 3);
// }
int dbus_monitor(void)
{
   
    DBusConnection *connection;
    DBusError error;
    dbus_error_init(&error);
    syslog(LOG_ERR,"ZTTT--file=[%s]--fun=[%s]--line=[%d]-Connection Error:[%s]",__FILE__,__FUNCTION__,__LINE__,error.message);
    // Connect to session bus
    connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
    if (dbus_error_is_set(&error))
    {
        fprintf(stderr, "Connection Error (%s)\n", error.message);
        syslog(LOG_ERR,"ZTTT--file=[%s]--fun=[%s]--line=[%d]-Connection Error:[%s]",__FILE__,__FUNCTION__,__LINE__,error.message);
        dbus_error_free(&error);
        return 1;
    }

    // Add a rule for incoming signals
    dbus_bus_add_match(connection, "type='signal',interface='org.freedesktop.login1.Manager'", &error);
    dbus_connection_flush(connection);

    if (dbus_error_is_set(&error))
    {
        fprintf(stderr, "Error adding D-Bus match rule (%s)\n", error.message);
        syslog(LOG_ERR,"ZTTT--file=[%s]--fun=[%s]--line=[%d]-Connection Error:[%s]",__FILE__,__FUNCTION__,__LINE__,error.message);
        dbus_error_free(&error);
        return 1;
    }

    // Main event loop
    while (1)
    {
        DBusMessage *message;
        DBusMessageIter args;
        bool sigvalue;
        DBusDispatchStatus status = dbus_connection_read_write(connection, 1000); // 设置阻塞时间
        // Blocking call to receive a message
        message = dbus_connection_pop_message(connection);
        printf("dbus_connection_read_write_dispatch ret=%d\n", status);

        if (message != NULL)
        {
            if (dbus_message_is_signal(message, "org.freedesktop.login1.Manager", "PrepareForShutdown"))
            {
                // 读取参数
                if (!dbus_message_iter_init(message, &args))
                    fprintf(stderr, "消息没有参数！\n");
                else if (DBUS_TYPE_BOOLEAN != dbus_message_iter_get_arg_type(&args))
                    fprintf(stderr, "参数格式错误！\n");
                else
                {
                    dbus_message_iter_get_basic(&args, &sigvalue);
                    printf("获取信号的值： %d\n", sigvalue);
                    syslog(LOG_ERR, "ZTTT--file=[%s]--fun=[%s]--line=[%d]-获取信号的值:[%d]", __FILE__, __FUNCTION__, __LINE__, sigvalue);
                    if (sigvalue == TRUE) // 是关机前信号
                    {
                        ////函数处理
                        ////获取到信号，do what you do.....
                        syslog(LOG_INFO, "------关机信号-----");
                        sd_bus *bus = NULL;
                        sd_bus_message *reply = NULL;
                        sd_bus_error error = SD_BUS_ERROR_NULL;
                        const char *who = "ostree-restore";
                        const char *why = "Performing some operations before shutdown";
                        const char *mode = "block";
                        int fd;
                        int r;

                        // Connect to the system bus
                        r = sd_bus_open_system(&bus);
                        if (r < 0)
                        {
                            fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
                            exit(EXIT_FAILURE);
                        }

                        // Call Inhibit method to block shutdown
                        r = sd_bus_call_method(bus,
                                               "org.freedesktop.login1",
                                               "/org/freedesktop/login1",
                                               "org.freedesktop.login1.Manager",
                                               "Inhibit",
                                               &error,
                                               &reply,
                                               "ssss", "shutdown", who, why, mode);
                        if (r < 0)
                        {
                            fprintf(stderr, "Failed to inhibit shutdown: %s\n", error.message);
                            exit(EXIT_FAILURE);
                        }

                        // Get the file descriptor from the reply message
                        r = sd_bus_message_read_basic(reply, 'h', &fd);
                        if (r < 0)
                        {
                            fprintf(stderr, "Failed to read reply message: %s\n", strerror(-r));
                            exit(EXIT_FAILURE);
                        }

                        // Close the reply message and release the file descriptor
                        sd_bus_message_unref(reply);

                        FILE *file = fopen("/etc/restore.txt", "r");
                        if (file == NULL)
                        {
                            printf("无法打开文件");
                            return 1;
                        }

                        char line[256];
                        char *result[100]; // 假设最多有100个结果
                        int count = 0;

                        while (fgets(line, sizeof(line), file))
                        {
                            char *level2_pos = strstr(line, "LEVEL2=");
                            if (level2_pos != NULL)
                            {
                                char *token = strtok(level2_pos + strlen("LEVEL2="), ";");
                                while (token != NULL && count < 100)
                                {
                                    result[count] = token;
                                    count++;
                                    token = strtok(NULL, ";");
                                }
                            }
                        }
                        fclose(file);
                        // 输出结果
                        for (int i = 0; i < count; i++)
                        {
                            syslog(LOG_INFO,"%s\n", result[i]);
                            char command[255] = {};
                            // snprintf(command,sizeof(command),"%s %s %s %s", "/etc/ostree-extra-developer/developer.sh", value,config,log);
                            snprintf(command, sizeof(command), "%s %s", "/usr/ost-ex.d/restore.sh", result[i]);
                            if (system(command) == 0)
                            {
                                syslog(LOG_INFO, "set restore success");
                            }
                        }
                        syslog(LOG_INFO, "------restort end-----");
                        syslog(LOG_INFO, "------关机信号end-----");
                        close(fd);
                        sd_bus_close(bus);
                    }
                }
            }
            // Free the received message
            dbus_message_unref(message);
        }
    }
    // Close the connection
    dbus_connection_unref(connection);
    return 0;
}


// int inhibit(void) {
//     sd_bus *bus = NULL;
//     sd_bus_message *reply = NULL;
//     sd_bus_error error = SD_BUS_ERROR_NULL;
//     const char *who = "ostree-restore";
//     const char *why = "Performing some operations before shutdown";
//     const char *mode = "block";
//     int fd;
//     int r;

//     // Connect to the system bus
//     r = sd_bus_open_system(&bus);
//     if (r < 0) {
//         fprintf(stderr, "Failed to connect to system bus: %s\n", strerror(-r));
//         exit(EXIT_FAILURE);
//     }

//     // Call Inhibit method to block shutdown
//     r = sd_bus_call_method(bus,
//                            "org.freedesktop.login1",
//                            "/org/freedesktop/login1",
//                            "org.freedesktop.login1.Manager",
//                            "Inhibit",
//                            &error,
//                            &reply,
//                            "ssss", "shutdown", who, why, mode);
//     if (r < 0) {
//         fprintf(stderr, "Failed to inhibit shutdown: %s\n", error.message);
//         exit(EXIT_FAILURE);
//     }

//     // Get the file descriptor from the reply message
//     r = sd_bus_message_read_basic(reply, 'h', &fd);
//     if (r < 0) {
//         fprintf(stderr, "Failed to read reply message: %s\n", strerror(-r));
//         exit(EXIT_FAILURE);
//     }

//     // Close the reply message and release the file descriptor
//     sd_bus_message_unref(reply);

//     syslog(LOG_INFO,"------restort start-----");
//     // Perform your operations here...
   
//     // Release the inhibition to allow shutdown
//     // r = sd_bus_call_method(bus,
//     //                        "org.freedesktop.login1",
//     //                        "/org/freedesktop/login1",
//     //                        "org.freedesktop.login1.Manager",
//     //                        "Uninhibit",
//     //                        &error,
//     //                        NULL,
//     //                        "ss", "shutdown", who);
//     // if (r < 0) {
//     //     fprintf(stderr, "Failed to uninhibit shutdown: %s\n", error.message);
//     //     exit(EXIT_FAILURE);
//     // }

//     // Close the connection to the bus
//     sd_bus_close(bus);
//     close(fd);
//     return 0;
// }

int
main (int argc, char *argv[])
{
    syslog(LOG_INFO,"test");
    // if (!pthread_create(&file_tid, NULL, dbus_monitor, NULL))
    // {
    //     syslog(LOG_INFO, "kyfs_fuse_init");
    // }
    dbus_monitor();
    return 0;
    
}