#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <linux/highmem.h>
#include "dm-verity-debug.h"
#include <linux/kdev_t.h>
#include<linux/sysfs.h> 
#include<linux/kobject.h>

#define ALTA_BUF_SIZE    4096
char* alta_buf;
size_t * alta_offset,alta_size;

struct kobject *kobj_ref;


void set_print_buf(char * buf, size_t * offset, size_t size){
    alta_buf = buf;
    alta_offset = offset;
    alta_size = size;

    *alta_offset = 0;
}


void alta_print(const char *fmt, ...)
{
    size_t offset = *alta_offset;

    va_list aptr;
    va_start(aptr, fmt);
    *alta_offset += vscnprintf(alta_buf+offset,(size_t)alta_size - offset, fmt, aptr);
    va_end(aptr);
}

static void show_fc_blks_list(void){
    int i = 0;

    if(empty_b_info()){
        return;
    }

    if(get_fec_correct_blks() == 0){
        alta_print("\n");
        return;
    }

    if ((long long) MAX_FC_BLKS_LIST <= get_fec_correct_blks()){  
        alta_print(",\"fc_dev\":\"%s\"",b_info->dev_name[b_info->list_idx]);
        alta_print(",\"fc_blk\":\"%llu\"",b_info->fc_blks_list[b_info->list_idx]);
        i = (b_info->list_idx + 1) % MAX_FC_BLKS_LIST;
    }


    for( ; i != b_info->list_idx; i = (i + 1) % MAX_FC_BLKS_LIST){
        alta_print(",\"fc_dev\":\"%s\"",b_info->dev_name[i]);
        alta_print(",\"fc_blk\":\"%llu\"",b_info->fc_blks_list[i]);
    }
    alta_print("\n");
}

static void show_dmv_ctr_list(void){
    int i = 0, ctr_cnt = get_dmv_ctr_cnt();

    if(empty_b_info()){
        return;
    }

    alta_print(",\"dmv_dev_cnt\":\"%d\"",ctr_cnt);

    for( ; i < ctr_cnt; i++)
        alta_print(",\"dmv_dev\":\"%s\"",b_info->dmv_ctr_list[i]);
}

static void show_blks_cnt(void){
    int i,foc = get_fec_off_cnt();

    if(empty_b_info()){
        return;
    }
    alta_print("\"total_blks\":\"%llu\"",get_total_blks());
    alta_print(",\"skipped_blks\":\"%llu\"",get_skipped_blks());
    alta_print(",\"corrupted_blks\":\"%llu\"",get_corrupted_blks());
    alta_print(",\"fec_correct_blks\":\"%llu\"",get_fec_correct_blks());

    if(foc > 0){
        alta_print(",\"fec_off_cnt\":\"%d\"",foc);
        for(i = 0 ; i < foc; i++)
            alta_print(",\"fec_off_dev\":\"%s\"",b_info->fec_off_list[i]);
    }
}


ssize_t alta_bigdata_read(struct file *filep, char __user *buf, size_t size, loff_t *offset){
    ssize_t ret;
    size_t proc_offset = 0;
    char* proc_buf = kzalloc(ALTA_BUF_SIZE, GFP_KERNEL);

    if(!proc_buf)
        return -ENOMEM;

    set_print_buf(proc_buf,&proc_offset,ALTA_BUF_SIZE);

    /* Print DMV info */
    if(empty_b_info()){
        alta_print("\"ERROR\":\"b_info_empty\"\n");
    }
    else {
        show_blks_cnt();
        show_dmv_ctr_list();
        show_fc_blks_list();
    }

    ret = simple_read_from_buffer(buf, size, offset, proc_buf, proc_offset);
    kfree(proc_buf);

    return ret; 
}

static ssize_t sysfs_show(struct kobject *kobj, 
        struct kobj_attribute *attr, char *buf)
{
    size_t sysfs_offset;
    set_print_buf(buf, &sysfs_offset, PAGE_SIZE);

    /* Print DMV info */
    if(empty_b_info()){
        alta_print("\"ERROR\":\"b_info_empty\"\n");
    }
    else {
        show_blks_cnt();
        show_dmv_ctr_list();
        show_fc_blks_list();
    }

    return sysfs_offset;
}


static const struct file_operations alta_proc_fops = {
    .owner          = THIS_MODULE,
    .read           = alta_bigdata_read,
};

struct kobj_attribute alta_attr = __ATTR(dmv_info, 0444, sysfs_show, NULL);

static int __init alta_bigdata_init(void){
    if(proc_create("alta_bigdata",0444,NULL,&alta_proc_fops) == NULL){
        printk(KERN_ERR "alta_bigdata: Error creating proc entry");
        goto bad_proc;
    }

    /*Creating a directory in /sys/kernel/ */
    kobj_ref = kobject_create_and_add("alta_bigdata",kernel_kobj);

    /*Creating sysfs file for dmv_info*/
    if(sysfs_create_file(kobj_ref,&alta_attr.attr)){
        printk(KERN_INFO"alta_bigdata: Cannot create sysfs file......\n");
        goto bad_sysfs;
    }

    pr_info("alta_bigdata : create /proc/alta_bigdata");
    return 0;

bad_sysfs:
    kobject_put(kobj_ref); 
    sysfs_remove_file(kernel_kobj, &alta_attr.attr);

bad_proc:
    free_b_info();
    remove_proc_entry("alta_bigdata", NULL);

    return -1;
}

static void __exit alta_bigdata_exit(void){
    kobject_put(kobj_ref); 
    sysfs_remove_file(kernel_kobj, &alta_attr.attr);

    free_b_info();
    remove_proc_entry("alta_bigdata", NULL);
}
module_init(alta_bigdata_init);
module_exit(alta_bigdata_exit);
