#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/stat.h>

#include "ulog.h"
#include "log_common.h"

#define FILTER_CONTENT  ":msg,contains,\""MODULE_FMT"\"\n"

#define BAK_FILE        "/tmp/%s"

int write_log_conf(const u8 level, const char *conf_path, const char *conf_file, const char *filter_mod,
          int (*cb_content)(FILE *fp, const u8 level, const char *filter_mod, void *arg), void *arg)
{
    FILE *fp = NULL;
    int ret = 1;
    u8 exist_backup = 1;

    /********** rsyslog configure **********/
    char conf_path_file[MAX_PATH_SZ];
    snprintf(conf_path_file, sizeof(conf_path_file), "%s%s", conf_path, conf_file);

    char bak_file[MAX_PATH_SZ];
    snprintf(bak_file, sizeof(bak_file), BAK_FILE, conf_file);
    if (rename(conf_path_file, bak_file) < 0) {
        if (errno == ENOENT) {
            exist_backup = 0;
            ULOG_INFO(g_log, "Been not exist, Configure file:%s is need to backup");
        } else {
            ULOG_ERR(g_log, "Baking configure file:%s is failure:%s  %d", conf_path_file, strerror(errno), errno);
            return ret;
        }        
    }  
    
    fp = fopen(conf_path_file, "w");
    if (fp == NULL) {
        ULOG_ERR(g_log, "Opening log configure file:%s is failure:%s", conf_path_file, strerror(errno));
        goto END;
    }

    ULOG_DEBUG(g_log, "cb_content:%x", cb_content);
    if (cb_content(fp, level, filter_mod, arg) != 0) {
        ULOG_ERR(g_log, "Callback log content is failure");
        goto END;
    }

    ret = 0;
END:
    if (fp != NULL) {
        fclose(fp);
    }

    if ((ret == 1) && (exist_backup == 1)) {
        // 恢复备份配置
        if (rename(bak_file, conf_path_file) < 0) {
            ULOG_ERR(g_log, "Restoring configure file:%s is failure:%s", conf_path_file, strerror(errno));
        }  
    }
    
    return ret;
}

int write_conf_content(FILE *fp, const u8 level, const char *filter_mod, void *arg)
{
    int i;
    int ret = 1;
    char line[MAX_LINE_SZ + 100] = {0};
    ULOG_INFO(g_log, "filter module:%s\n", filter_mod);
    if ((filter_mod != NULL) && (strlen(filter_mod) > 0)) {
        snprintf(line, sizeof(line), FILTER_CONTENT, filter_mod);
        if (fputs(line, fp) == EOF) {
            ULOG_ERR(g_log, "Message filter:%s of configure file which is written is failure:%s", 
                        filter_mod, strerror(errno));
            goto END;
        }
    }
    
    char tmp[20];
    line[0] = '\0';     // 清零
    for (i = 0; i <= level;) {
        if (snprintf(tmp, sizeof(tmp), "*.=%s", g_level_array[i].str) < 0) {
            ULOG_ERR(g_log, "Setting content of log file configure is failure");
            goto END;
        }
        strcat(line, tmp);
        i++;
        if (level >= i) {
            strcat(line, ";");
        }
    }
    strcat(line, "     ");

    strcat(line, (const char *)arg);
    strcat(line, "\n");

    if (fputs(line, fp) == EOF) {
        ULOG_ERR(g_log, "Configure file which is written is failure:%s", strerror(errno));
        goto END;
    }

    ret = 0;
END:
    return ret;
}

int modify_authorizing(const char *redirect_path)
{
    if (chmod(redirect_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH) < 0) {       
        ULOG_ERR(g_log, "Authorizing of %s which is modified is failure:%s", redirect_path, strerror(errno));
        return 1;
    }
    return 0;
}

int write_conf_content_authorizing(FILE *fp, const u8 level,             const char *filter_mod, void *arg)
{
    if (write_conf_content(fp, level, filter_mod, arg) != 0) {
        ULOG_ERR(g_log, "configure of log conosle which is written is failure");
        return 1;
    } 
    
    if (modify_authorizing((const char *)arg) != 0) {
        ULOG_ERR(g_log, "Modifying authorizing of %s is failure", (const char *)arg);
        return 1;
    }

    return 0;
}