#include <glib.h>
#include <gio/gio.h>
#include <glib/gstdio.h>

#define BUFFER_SIZE 1024

#define OVL_DIR_PRE "/ostree/pkgs/ovl-"

#define ETC_LAYER_LOWER "/etc-ovl/etc-lower/"
#define ETC_LAYER_UPPER "/etc-ovl/etc-upper/"
#define ETC_LAYER_TMP_UPPER "/etc-ovl/etc-tmpupper/"
#define ETC_LAYER_WORK "/etc-ovl/etc-work/"

#define USR_LAYER_LOWER "/usr-ovl/usr-lower/"
#define USR_LAYER_TMP_UPPER "/usr-ovl/usr-tmpupper/"
#define USR_LAYER_WORK "/usr-ovl/usr-work/"

#define VAR_LAYER_LOWER "/var-ovl/var-lower/"
#define VAR_LAYER_UPPER "/var-ovl/var-upper/"
#define VAR_LAYER_TMP_UPPER "/var-ovl/var-tmpupper/"
#define VAR_LAYER_WORK "/var-ovl/var-work/" 

gboolean create_pending_deploy_dir(const gchar *hash_value)
{
    gchar *ovl_etc_lower = g_strconcat (OVL_DIR_PRE, hash_value, ETC_LAYER_LOWER, NULL);
    if (g_mkdir_with_parents(ovl_etc_lower, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    }    

    gchar *ovl_etc_upper = g_strconcat (OVL_DIR_PRE, hash_value, ETC_LAYER_UPPER, NULL);
    if (g_mkdir_with_parents(ovl_etc_upper, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    }   

    gchar *ovl_etc_tmp_upper = g_strconcat (OVL_DIR_PRE, hash_value, ETC_LAYER_TMP_UPPER, NULL);
    if (g_mkdir_with_parents(ovl_etc_tmp_upper, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    } 
    gchar *ovl_etc_work = g_strconcat (OVL_DIR_PRE, hash_value, ETC_LAYER_WORK, NULL);
    if (g_mkdir_with_parents(ovl_etc_work, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    } 

    gchar *ovl_usr_lower = g_strconcat (OVL_DIR_PRE, hash_value, USR_LAYER_LOWER, NULL);
    if (g_mkdir_with_parents(ovl_usr_lower, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    } 
    gchar *ovl_usr_tmp_upper = g_strconcat (OVL_DIR_PRE, hash_value, USR_LAYER_TMP_UPPER, NULL);
    if (g_mkdir_with_parents(ovl_usr_tmp_upper, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    } 
    gchar *ovl_usr_work = g_strconcat (OVL_DIR_PRE, hash_value, USR_LAYER_WORK, NULL);
    if (g_mkdir_with_parents(ovl_usr_work, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    } 

    gchar *ovl_var_lower = g_strconcat (OVL_DIR_PRE, hash_value, VAR_LAYER_LOWER, NULL);
    if (g_mkdir_with_parents(ovl_var_lower, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    } 
    gchar *ovl_var_upper = g_strconcat (OVL_DIR_PRE, hash_value, VAR_LAYER_UPPER, NULL);
    if (g_mkdir_with_parents(ovl_var_upper, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    } 
    gchar *ovl_var_tmp_upper = g_strconcat (OVL_DIR_PRE, hash_value, VAR_LAYER_TMP_UPPER, NULL);
    if (g_mkdir_with_parents(ovl_var_tmp_upper, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    } 
    gchar *ovl_var_work = g_strconcat (OVL_DIR_PRE, hash_value, VAR_LAYER_WORK, NULL);
    if (g_mkdir_with_parents(ovl_var_work, 0755) == -1)
    {
       g_info("make ovl dir failed.");
       return FALSE;
    } 

    return TRUE;
}

gchar* get_pending_deploy_hash(const gchar* line)
{
    const gchar *pending_pos = strstr(line, "pending");
    if(pending_pos == NULL)
    {
        return NULL;
    }

    const gchar *hash_start = strstr(line, "openkylin ");
    if (hash_start == NULL || hash_start > pending_pos)
    {
        return NULL;
    }
    
    hash_start += strlen("openkylin ");

    const char* hash_end = strchr(hash_start, ' ');
    if (hash_end == NULL )
    {
        hash_end = strchr(hash_start, '\n');
        if (hash_end == NULL)
        {
            hash_end = strchr (hash_start, '\0');
        }
        
    }
    
    size_t hash_len = hash_end - hash_start;
    if (hash_len == 0)
    {
        return NULL;
    }

    gchar *hash_value = g_malloc(hash_len + 1);
    strncpy(hash_value, hash_start, hash_len);
    hash_value[hash_len] = '\0';

    return hash_value;
    
}


int main (int argc, char **argv)
{
    FILE *file = popen("ostree admin status", "r");
    if (file == NULL)
    {
        g_info("ostree admin status failed.");
        return 0;
    }
    
    gchar buffer[BUFFER_SIZE];
    while (fgets(buffer, sizeof(buffer), file))
    {
        gchar *pending_hash = get_pending_deploy_hash(buffer);
        if (pending_hash != NULL)
        {
            g_print("pending hash value: %s\n", pending_hash);
            //创建相应的ovl目录
            create_pending_deploy_dir(pending_hash);
        }
    }

    pclose(file);

}