/* Copyright (c) KylinSoft  Co., Ltd. [2023].All rights reserved.
    [ostree-maintain-daemon] licensed under the [Your LICENSE].
    Author: [ZhangTingting]
    Create: [2024]
*/

#include "mm-pkgs-db.h"

gboolean mm_init_db_file(const gchar *file_path)
{
    GFileOutputStream *stream;
    GError *error = NULL;

    GFile *file = g_file_new_for_path(file_path);
    if (g_file_query_exists(file, NULL)) {
        g_print("ostree-pkgs.db has already exists.\n");
        return TRUE;
    }

    g_print("ostree-pkgs.db not exists, now create it...\n");
    stream = g_file_create(file, G_FILE_CREATE_NONE, NULL, &error);
    if (error != NULL) {
        g_error_free(error);
        g_print("ostree-ovl.conf create failed.\n");
        return FALSE;
    }
    g_print("ostree-ovl.conf create sccuess.\n");

    g_object_unref(stream);
    g_object_unref(file);

    return TRUE;
}

/*********退出维护模式时写入安装包数据库*********/
gboolean mm_update_pkgs_db(void)
{
    GFile *file;
    GFileInputStream *in_stream;
    GBufferedInputStream *buffered_stream;
    GDataInputStream *data_stream;
    gsize len = 0;
    gchar *line = NULL;
    GError *error = NULL;

    g_info("mm exit: update pkgs db start.");
    // Get MM start time
    gchar *mm_start_time = mm_get_config_value(MM_CONFIG_FILE_PATH, TIME_SECTION, TIME_START);
    GDateTime *date_time_start = g_date_time_new_from_iso8601(mm_start_time, NULL);

    if (!date_time_start) {
        g_free(mm_start_time);
        g_date_time_unref(date_time_start);
        g_info("mm exit:Get MM start time failed!");
        return FALSE;
    }
    g_info("mm exit: update pkgs db start time = %s.", mm_start_time);

    // Get pkgs install list
    file = g_file_new_for_path(PKGS_INFO_FILE);
    in_stream = g_file_read(file, NULL, &error);
    if (error != NULL) {
        g_info("Error open dpkg log file: %s.", error->message);
        g_error_free(error);
        g_object_unref(file);
        return FALSE;
    }

    buffered_stream = g_buffered_input_stream_new(G_INPUT_STREAM(in_stream));
    data_stream = g_data_input_stream_new(G_INPUT_STREAM(buffered_stream));

    // write to db file
    GFile *db_file;
    GFileOutputStream *db_out_stream;
    gsize bytes_written;

    db_file = g_file_new_for_path(PKGS_DB_PATH);
    db_out_stream = g_file_append_to(db_file, G_FILE_CREATE_NONE, NULL, &error);
    if (error != NULL) {
        g_printerr("Error open dpkg log file: %s\n", error->message);
        g_error_free(error);
        g_object_unref(file);
        g_object_unref(db_file);
        return FALSE;
    }

    while (line = g_data_input_stream_read_line(data_stream, &len, NULL, &error)) {
        gchar *curr_line_str = g_strndup(line, 20);
        curr_line_str[10] = 'T';
        curr_line_str[19] = 'Z';
        curr_line_str[20] = '\0';

        GDateTime *curr_line_time = g_date_time_new_from_iso8601(curr_line_str, NULL);

        if (curr_line_time) {
            if (g_date_time_compare(curr_line_time, date_time_start) > 0) {
                if (g_strstr_len(line, -1, "desktop-file-utils") || g_strstr_len(line, -1, "mime-support") || g_strstr_len(line, -1, "bamfdaemon")) {
                    continue;
                }

                if (g_strstr_len(line, -1, "status installed") || g_strstr_len(line, -1, "not installed")) {
                    // g_print("%s\n", line);
                    g_output_stream_write(G_OUTPUT_STREAM(db_out_stream), line, strlen(line), NULL, &error);
                    if (error != NULL) {
                        g_printerr("Error write dpkg db file: %s\n", error->message);
                        g_error_free(error);
                        g_object_unref(file);
                        g_object_unref(db_file);
                        return FALSE;
                    }
                    const gchar *newline = "\n";
                    g_output_stream_write(G_OUTPUT_STREAM(db_out_stream), newline, strlen(newline), NULL, &error);
                    if (error != NULL) {
                        g_printerr("Error write dpkg db file: %s\n", error->message);
                        g_error_free(error);
                        g_object_unref(file);
                        g_object_unref(db_file);
                        return FALSE;
                    }
                    g_output_stream_flush(G_OUTPUT_STREAM(db_out_stream), NULL, &error);
                }
            }
        }
    }

    g_object_unref(in_stream);
    g_object_unref(file);
    g_object_unref(db_out_stream);
    g_object_unref(db_file);

    return TRUE;
}