#define _LARGEFILE64_SOURCE

#define LOG_TAG "f2fs_sparseblock"


#include <cutils/log.h>
#include <fcntl.h>
#include <f2fs_fs.h>
#include <linux/types.h>
#include <sys/stat.h>
#include "f2fs_sparseblock.h"


#define D_DISP_u32(ptr, member)           \
  do {                \
    SLOGD("%-30s" "\t\t[0x%#08x : %u]\n",    \
      #member, le32_to_cpu((ptr)->member), le32_to_cpu((ptr)->member) );  \
  } while (0);

#define D_DISP_u64(ptr, member)           \
  do {                \
    SLOGD("%-30s" "\t\t[0x%#016llx : %llu]\n",    \
      #member, le64_to_cpu((ptr)->member), le64_to_cpu((ptr)->member) );  \
  } while (0);

#define segno_in_journal(sum, i)    (sum->sit_j.entries[i].segno)

#define sit_in_journal(sum, i)      (sum->sit_j.entries[i].se)

static void dbg_print_raw_sb_info(struct f2fs_super_block *sb)
{
    SLOGD("\n");
    SLOGD("+--------------------------------------------------------+\n");
    SLOGD("| Super block                                            |\n");
    SLOGD("+--------------------------------------------------------+\n");

    D_DISP_u32(sb, magic);
    D_DISP_u32(sb, major_ver);
    D_DISP_u32(sb, minor_ver);
    D_DISP_u32(sb, log_sectorsize);
    D_DISP_u32(sb, log_sectors_per_block);

    D_DISP_u32(sb, log_blocksize);
    D_DISP_u32(sb, log_blocks_per_seg);
    D_DISP_u32(sb, segs_per_sec);
    D_DISP_u32(sb, secs_per_zone);
    D_DISP_u32(sb, checksum_offset);
    D_DISP_u64(sb, block_count);

    D_DISP_u32(sb, section_count);
    D_DISP_u32(sb, segment_count);
    D_DISP_u32(sb, segment_count_ckpt);
    D_DISP_u32(sb, segment_count_sit);
    D_DISP_u32(sb, segment_count_nat);

    D_DISP_u32(sb, segment_count_ssa);
    D_DISP_u32(sb, segment_count_main);
    D_DISP_u32(sb, segment0_blkaddr);

    D_DISP_u32(sb, cp_blkaddr);
    D_DISP_u32(sb, sit_blkaddr);
    D_DISP_u32(sb, nat_blkaddr);
    D_DISP_u32(sb, ssa_blkaddr);
    D_DISP_u32(sb, main_blkaddr);

    D_DISP_u32(sb, root_ino);
    D_DISP_u32(sb, node_ino);
    D_DISP_u32(sb, meta_ino);
    D_DISP_u32(sb, cp_payload);
    SLOGD("\n");
}
static void dbg_print_raw_ckpt_struct(struct f2fs_checkpoint *cp)
{
    SLOGD("\n");
    SLOGD("+--------------------------------------------------------+\n");
    SLOGD("| Checkpoint                                             |\n");
    SLOGD("+--------------------------------------------------------+\n");

    D_DISP_u64(cp, checkpoint_ver);
    D_DISP_u64(cp, user_block_count);
    D_DISP_u64(cp, valid_block_count);
    D_DISP_u32(cp, rsvd_segment_count);
    D_DISP_u32(cp, overprov_segment_count);
    D_DISP_u32(cp, free_segment_count);

    D_DISP_u32(cp, alloc_type[CURSEG_HOT_NODE]);
    D_DISP_u32(cp, alloc_type[CURSEG_WARM_NODE]);
    D_DISP_u32(cp, alloc_type[CURSEG_COLD_NODE]);
    D_DISP_u32(cp, cur_node_segno[0]);
    D_DISP_u32(cp, cur_node_segno[1]);
    D_DISP_u32(cp, cur_node_segno[2]);

    D_DISP_u32(cp, cur_node_blkoff[0]);
    D_DISP_u32(cp, cur_node_blkoff[1]);
    D_DISP_u32(cp, cur_node_blkoff[2]);


    D_DISP_u32(cp, alloc_type[CURSEG_HOT_DATA]);
    D_DISP_u32(cp, alloc_type[CURSEG_WARM_DATA]);
    D_DISP_u32(cp, alloc_type[CURSEG_COLD_DATA]);
    D_DISP_u32(cp, cur_data_segno[0]);
    D_DISP_u32(cp, cur_data_segno[1]);
    D_DISP_u32(cp, cur_data_segno[2]);

    D_DISP_u32(cp, cur_data_blkoff[0]);
    D_DISP_u32(cp, cur_data_blkoff[1]);
    D_DISP_u32(cp, cur_data_blkoff[2]);

    D_DISP_u32(cp, ckpt_flags);
    D_DISP_u32(cp, cp_pack_total_block_count);
    D_DISP_u32(cp, cp_pack_start_sum);
    D_DISP_u32(cp, valid_node_count);
    D_DISP_u32(cp, valid_inode_count);
    D_DISP_u32(cp, next_free_nid);
    D_DISP_u32(cp, sit_ver_bitmap_bytesize);
    D_DISP_u32(cp, nat_ver_bitmap_bytesize);
    D_DISP_u32(cp, checksum_offset);
    D_DISP_u64(cp, elapsed_time);

    D_DISP_u32(cp, sit_nat_version_bitmap[0]);
    SLOGD("\n\n");
}

static void dbg_print_info_struct(struct f2fs_info *info)
{
    SLOGD("\n");
    SLOGD("+--------------------------------------------------------+\n");
    SLOGD("| F2FS_INFO                                              |\n");
    SLOGD("+--------------------------------------------------------+\n");
    SLOGD("blocks_per_segment: %"PRIu64, info->blocks_per_segment);
    SLOGD("block_size: %d", info->block_size);
    SLOGD("sit_bmp loc: %p", info->sit_bmp);
    SLOGD("sit_bmp_size: %d", info->sit_bmp_size);
    SLOGD("blocks_per_sit: %"PRIu64, info->blocks_per_sit);
    SLOGD("sit_blocks loc: %p", info->sit_blocks);
    SLOGD("sit_sums loc: %p", info->sit_sums);
    SLOGD("sit_sums num: %d", le16_to_cpu(info->sit_sums->n_sits));
    unsigned int i;
    for(i = 0; i < (le16_to_cpu(info->sit_sums->n_sits)); i++) {
        SLOGD("entry %d in journal entries is for segment %d",i, le32_to_cpu(segno_in_journal(info->sit_sums, i)));
    }

    SLOGD("cp_blkaddr: %"PRIu64, info->cp_blkaddr);
    SLOGD("cp_valid_cp_blkaddr: %"PRIu64, info->cp_valid_cp_blkaddr);
    SLOGD("sit_blkaddr: %"PRIu64, info->sit_blkaddr);
    SLOGD("nat_blkaddr: %"PRIu64, info->nat_blkaddr);
    SLOGD("ssa_blkaddr: %"PRIu64, info->ssa_blkaddr);
    SLOGD("main_blkaddr: %"PRIu64, info->main_blkaddr);
    SLOGD("total_user_used: %"PRIu64, info->total_user_used);
    SLOGD("total_blocks: %"PRIu64, info->total_blocks);
    SLOGD("\n\n");
}


/* read blocks */
static int read_structure(int fd, unsigned long long start, void *buf, ssize_t len)
{
    off64_t ret;

    ret = lseek64(fd, start, SEEK_SET);
    if (ret < 0) {
        SLOGE("failed to seek\n");
        return ret;
    }

    ret = read(fd, buf, len);
    if (ret < 0) {
        SLOGE("failed to read\n");
        return ret;
    }
    if (ret != len) {
        SLOGE("failed to read all\n");
        return -1;
    }
    return 0;
}

static int read_structure_blk(int fd, unsigned long long start_blk, void *buf, size_t len)
{
    return read_structure(fd, F2FS_BLKSIZE*start_blk, buf, F2FS_BLKSIZE * len);
}

static int read_f2fs_sb(int fd, struct f2fs_super_block *sb)
{
    int rc;
    rc = read_structure(fd, F2FS_SUPER_OFFSET, sb, sizeof(*sb));
    if (le32_to_cpu(sb->magic) != F2FS_SUPER_MAGIC) {
        SLOGE("Not a valid F2FS super block. Magic:%#08x != %#08x",
                                  le32_to_cpu(sb->magic), F2FS_SUPER_MAGIC);
        return -1;
    }
    return 0;
}

unsigned int get_f2fs_filesystem_size_sec(char *dev)
{
    int fd;
    if ((fd = open(dev, O_RDONLY)) < 0) {
        SLOGE("Cannot open device to get filesystem size ");
        return 0;
    }
    struct f2fs_super_block sb;
    if(read_f2fs_sb(fd, &sb))
        return 0;
    return (unsigned int)(le64_to_cpu(sb.block_count)*F2FS_BLKSIZE/DEFAULT_SECTOR_SIZE);
}

static struct f2fs_checkpoint *validate_checkpoint(block_t cp_addr,
                                                   unsigned long long *version, int fd)
{
    unsigned char *cp_block_1, *cp_block_2;
    struct f2fs_checkpoint *cp_block, *cp_ret;
    u64 cp1_version = 0, cp2_version = 0;

    cp_block_1 = malloc(F2FS_BLKSIZE);
    if (!cp_block_1)
        return NULL;

    /* Read the 1st cp block in this CP pack */
    if (read_structure_blk(fd, cp_addr, cp_block_1, 1))
        goto invalid_cp1;

    /* get the version number */
    cp_block = (struct f2fs_checkpoint *)cp_block_1;

    cp1_version = le64_to_cpu(cp_block->checkpoint_ver);

    cp_block_2 = malloc(F2FS_BLKSIZE);
    if (!cp_block_2) {
        goto invalid_cp1;
    }
    /* Read the 2nd cp block in this CP pack */
    cp_addr += le32_to_cpu(cp_block->cp_pack_total_block_count) - 1;
    if (read_structure_blk(fd, cp_addr, cp_block_2, 1)) {
        goto invalid_cp2;
    }

    cp_block = (struct f2fs_checkpoint *)cp_block_2;

    cp2_version = le64_to_cpu(cp_block->checkpoint_ver);

    if (cp2_version == cp1_version) {
        *version = cp2_version;
        free(cp_block_2);
        return (struct f2fs_checkpoint *)cp_block_1;
    }

    /* There must be something wrong with this checkpoint */
invalid_cp2:
    free(cp_block_2);
invalid_cp1:
    free(cp_block_1);
    return NULL;
}

int get_valid_checkpoint_info(int fd, struct f2fs_super_block *sb, struct f2fs_checkpoint **cp,  struct f2fs_info *info)
{
    struct f2fs_checkpoint *cp_block;

    struct f2fs_checkpoint *cp1, *cp2, *cur_cp;
    int cur_cp_no;
    unsigned long blk_size;// = 1<<le32_to_cpu(info->sb->log_blocksize);
    unsigned long long cp1_version = 0, cp2_version = 0;
    unsigned long long cp1_start_blk_no;
    unsigned long long cp2_start_blk_no;
    u32 bmp_size;

    blk_size = 1U<<le32_to_cpu(sb->log_blocksize);

    /*
     * Find valid cp by reading both packs and finding most recent one.
     */
    cp1_start_blk_no = le32_to_cpu(sb->cp_blkaddr);
    cp1 = validate_checkpoint(cp1_start_blk_no, &cp1_version, fd);

    /* The second checkpoint pack should start at the next segment */
    cp2_start_blk_no = cp1_start_blk_no + (1 << le32_to_cpu(sb->log_blocks_per_seg));
    cp2 = validate_checkpoint(cp2_start_blk_no, &cp2_version, fd);

    if (cp1 && cp2) {
        if (ver_after(cp2_version, cp1_version)) {
            cur_cp = cp2;
            info->cp_valid_cp_blkaddr = cp2_start_blk_no;
            free(cp1);
        } else {
            cur_cp = cp1;
            info->cp_valid_cp_blkaddr = cp1_start_blk_no;
            free(cp2);
        }
    } else if (cp1) {
        cur_cp = cp1;
        info->cp_valid_cp_blkaddr = cp1_start_blk_no;
    } else if (cp2) {
        cur_cp = cp2;
        info->cp_valid_cp_blkaddr = cp2_start_blk_no;
    } else {
        goto fail_no_cp;
    }

    *cp = cur_cp;

    return 0;

fail_no_cp:
    SLOGE("Valid Checkpoint not found!!");
    return -EINVAL;
}

static int gather_sit_info(int fd, struct f2fs_info *info)
{
    u64 num_segments = (info->total_blocks - info->main_blkaddr
            + info->blocks_per_segment - 1) / info->blocks_per_segment;
    u64 num_sit_blocks = (num_segments + SIT_ENTRY_PER_BLOCK - 1) / SIT_ENTRY_PER_BLOCK;
    u64 sit_block;

    info->sit_blocks = malloc(num_sit_blocks * sizeof(struct f2fs_sit_block));
    if (!info->sit_blocks)
        return -1;

    for(sit_block = 0; sit_block<num_sit_blocks; sit_block++) {
        off64_t address = info->sit_blkaddr + sit_block;

        if (f2fs_test_bit(sit_block, info->sit_bmp))
            address += info->blocks_per_sit;

        SLOGD("Reading cache block starting at block %"PRIu64, address);
        if (read_structure(fd, address * F2FS_BLKSIZE, &info->sit_blocks[sit_block], sizeof(struct f2fs_sit_block))) {
            SLOGE("Could not read sit block at block %"PRIu64, address);
            free(info->sit_blocks);
            return -1;
        }
    }
    return 0;
}

static inline int is_set_ckpt_flags(struct f2fs_checkpoint *cp, unsigned int f)
{
    unsigned int ckpt_flags = le32_to_cpu(cp->ckpt_flags);
    return !!(ckpt_flags & f);
}

static inline u64 sum_blk_addr(struct f2fs_checkpoint *cp, struct f2fs_info *info, int base, int type)
{
    return info->cp_valid_cp_blkaddr + le32_to_cpu(cp->cp_pack_total_block_count)
                - (base + 1) + type;
}

static int get_sit_summary(int fd, struct f2fs_info *info, struct f2fs_checkpoint *cp)
{
    char buffer[F2FS_BLKSIZE];

    info->sit_sums = calloc(1, sizeof(struct f2fs_summary_block));
    if (!info->sit_sums)
        return -1;

    /* CURSEG_COLD_DATA where the journaled SIT entries are. */
    if (is_set_ckpt_flags(cp, CP_COMPACT_SUM_FLAG)) {
        if (read_structure_blk(fd, info->cp_valid_cp_blkaddr + le32_to_cpu(cp->cp_pack_start_sum), buffer, 1))
            return -1;
        memcpy(&info->sit_sums->n_sits, &buffer[SUM_JOURNAL_SIZE], SUM_JOURNAL_SIZE);
    } else {
        u64 blk_addr;
        if (is_set_ckpt_flags(cp, CP_UMOUNT_FLAG))
            blk_addr = sum_blk_addr(cp, info, NR_CURSEG_TYPE, CURSEG_COLD_DATA);
        else
            blk_addr = sum_blk_addr(cp, info, NR_CURSEG_DATA_TYPE, CURSEG_COLD_DATA);

        if (read_structure_blk(fd, blk_addr, buffer, 1))
            return -1;

        memcpy(info->sit_sums, buffer, sizeof(struct f2fs_summary_block));
    }
    return 0;
}

struct f2fs_info *generate_f2fs_info(int fd)
{
    struct f2fs_super_block *sb = NULL;
    struct f2fs_checkpoint *cp = NULL;
    struct f2fs_info *info;

    info = calloc(1, sizeof(*info));
    if (!info) {
        SLOGE("Out of memory!");
        return NULL;
    }

    sb = malloc(sizeof(*sb));
    if(!sb) {
        SLOGE("Out of memory!");
        free(info);
        return NULL;
    }
    if (read_f2fs_sb(fd, sb)) {
        SLOGE("Failed to read superblock");
        free(info);
        free(sb);
        return NULL;
    }
    dbg_print_raw_sb_info(sb);

    info->cp_blkaddr = le32_to_cpu(sb->cp_blkaddr);
    info->sit_blkaddr = le32_to_cpu(sb->sit_blkaddr);
    info->nat_blkaddr = le32_to_cpu(sb->nat_blkaddr);
    info->ssa_blkaddr = le32_to_cpu(sb->ssa_blkaddr);
    info->main_blkaddr = le32_to_cpu(sb->main_blkaddr);
    info->block_size = F2FS_BLKSIZE;
    info->total_blocks = sb->block_count;
    info->blocks_per_sit = (le32_to_cpu(sb->segment_count_sit) >> 1) << le32_to_cpu(sb->log_blocks_per_seg);
    info->blocks_per_segment = 1U << le32_to_cpu(sb->log_blocks_per_seg);

    if (get_valid_checkpoint_info(fd, sb, &cp, info))
        goto error;
    dbg_print_raw_ckpt_struct(cp);

    info->total_user_used = le32_to_cpu(cp->valid_block_count);

    u32 bmp_size = le32_to_cpu(cp->sit_ver_bitmap_bytesize);

    /* get sit validity bitmap */
    info->sit_bmp = malloc(bmp_size);
    if(!info->sit_bmp) {
        SLOGE("Out of memory!");
        goto error;
    }

    info->sit_bmp_size = bmp_size;
    if (read_structure(fd, info->cp_valid_cp_blkaddr * F2FS_BLKSIZE
                   + offsetof(struct f2fs_checkpoint, sit_nat_version_bitmap),
                   info->sit_bmp, bmp_size)) {
        SLOGE("Error getting SIT validity bitmap");
        goto error;
    }

    if (gather_sit_info(fd , info)) {
        SLOGE("Error getting SIT information");
        goto error;
    }
    if (get_sit_summary(fd, info, cp)) {
        SLOGE("Error getting SIT entries in summary area");
        goto error;
    }
    dbg_print_info_struct(info);
    return info;
error:
    free(sb);
    free(cp);
    free_f2fs_info(info);
    return NULL;
}

void free_f2fs_info(struct f2fs_info *info)
{
    if (info) {
        free(info->sit_blocks);
        info->sit_blocks = NULL;

        free(info->sit_bmp);
        info->sit_bmp = NULL;

        free(info->sit_sums);
        info->sit_sums = NULL;
    }
    free(info);
}

u64 get_num_blocks_used(struct f2fs_info *info)
{
    return info->main_blkaddr + info->total_user_used;
}

int f2fs_test_bit(unsigned int nr, const char *p)
{
    int mask;
    char *addr = (char *)p;

    addr += (nr >> 3);
    mask = 1 << (7 - (nr & 0x07));
    return (mask & *addr) != 0;
}

int run_on_used_blocks(u64 startblock, struct f2fs_info *info, int (*func)(u64 pos, void *data), void *data) {
    struct f2fs_sit_block sit_block_cache;
    struct f2fs_sit_entry * sit_entry;
    u64 sit_block_num_cur = 0, segnum = 0, block_offset;
    u64 block;
    unsigned int used, found, started = 0, i;

    for (block=startblock; block<info->total_blocks; block++) {
        /* TODO: Save only relevant portions of metadata */
        if (block < info->main_blkaddr) {
            if (func(block, data)) {
                SLOGI("func error");
                return -1;
            }
        } else {
            /* Main Section */
            segnum = (block - info->main_blkaddr)/info->blocks_per_segment;

            /* check the SIT entries in the journal */
            found = 0;
            for(i = 0; i < le16_to_cpu(info->sit_sums->n_sits); i++) {
                if (le32_to_cpu(segno_in_journal(info->sit_sums, i)) == segnum) {
                    sit_entry = &sit_in_journal(info->sit_sums, i);
                    found = 1;
                    break;
                }
            }

            /* get SIT entry from SIT section */
            if (!found) {
                sit_block_num_cur = segnum/SIT_ENTRY_PER_BLOCK;
                sit_entry = &info->sit_blocks[sit_block_num_cur].entries[segnum % SIT_ENTRY_PER_BLOCK];
            }

            block_offset = (block - info->main_blkaddr) % info->blocks_per_segment;

            used = f2fs_test_bit(block_offset, (char *)sit_entry->valid_map);
            if(used)
                if (func(block, data))
                    return -1;
        }
    }
    return 0;
}

struct privdata
{
    int count;
    int infd;
    int outfd;
    char* buf;
    char *zbuf;
    int done;
    struct f2fs_info *info;
};


/*
 * This is a simple test program. It performs a block to block copy of a
 * filesystem, replacing blocks identified as unused with 0's.
 */

int copy_used(u64 pos, void *data)
{
    struct privdata *d = data;
    char *buf;
    int pdone = (pos*100)/d->info->total_blocks;
    if (pdone > d->done) {
        d->done = pdone;
        printf("Done with %d percent\n", d->done);
    }

    d->count++;
    buf = d->buf;
    if(read_structure_blk(d->infd, (unsigned long long)pos, d->buf, 1)) {
        printf("Error reading!!!\n");
        return -1;
    }

    off64_t ret;
    ret = lseek64(d->outfd, pos*F2FS_BLKSIZE, SEEK_SET);
    if (ret < 0) {
        SLOGE("failed to seek\n");
        return ret;
    }

    ret = write(d->outfd, d->buf, F2FS_BLKSIZE);
    if (ret < 0) {
        SLOGE("failed to write\n");
        return ret;
    }
    if (ret != F2FS_BLKSIZE) {
        SLOGE("failed to read all\n");
        return -1;
    }
    return 0;
}

int main(int argc, char **argv)
{
    if (argc != 3)
        printf("Usage: %s fs_file_in fs_file_out\n", argv[0]);
    char *in = argv[1];
    char *out = argv[2];
    int infd, outfd;

    if ((infd = open(in, O_RDONLY)) < 0) {
        SLOGE("Cannot open device");
        return 0;
    }
    if ((outfd = open(out, O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR)) < 0) {
        SLOGE("Cannot open output");
        return 0;
    }

    struct privdata d;
    d.infd = infd;
    d.outfd = outfd;
    d.count = 0;
    struct f2fs_info *info = generate_f2fs_info(infd);
    if (!info) {
        printf("Failed to generate info!");
        return -1;
    }
    char *buf = malloc(F2FS_BLKSIZE);
    char *zbuf = calloc(1, F2FS_BLKSIZE);
    d.buf = buf;
    d.zbuf = zbuf;
    d.done = 0;
    d.info = info;
    int expected_count = get_num_blocks_used(info);
    run_on_used_blocks(0, info, &copy_used, &d);
    printf("Copied %d blocks. Expected to copy %d\n", d.count, expected_count);
    ftruncate64(outfd, info->total_blocks * F2FS_BLKSIZE);
    free_f2fs_info(info);
    free(buf);
    free(zbuf);
    close(infd);
    close(outfd);
    return 0;
}
