#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include "openssl/md5.h"
#include "mtd.h"
#include "libcpnv.h"
#include "cfg_api.h"
#include "flags_api.h"
#include "zxicbasic_api.h"


/*******************************************************************************
* 功能描述:     copyfile
* 参数说明:     
*   (传入参数)  to:目标文件
*   (传入参数)  from:源文件
* 返 回 值:     0表示成功,负值失败
* 其它说明:     
*******************************************************************************/
static int copyfile(const char *from, const char *to)
{
    int fd_to;
    int fd_from;
    char buf[4096];
    ssize_t nread;
    int ret = -1;

    fd_from = open(from, O_RDONLY);
    if (fd_from < 0)
        return -2;

    fd_to = open(to, O_RDWR | O_CREAT | O_TRUNC | O_SYNC, 0640);
    if (fd_to < 0) {
        ret = -3;
        goto out_error;
    }

    while (1)
    {
        char *out_ptr;
        ssize_t nwritten;

        nread = read(fd_from, buf, sizeof(buf));
        if (nread == 0)
        {
            break; /* read file done*/
        }
        else
        {
            if (nread < 0 )
            {
                if (errno == EINTR || errno == EAGAIN)
                {
                    continue;
                }
                else
                {
                    ret = -4;
                    goto out_error;
                }
            }
        }

        out_ptr = buf;
        do
        {
            nwritten = write(fd_to, out_ptr, nread);
            if (nwritten > 0)
            {
                nread -= nwritten;
                out_ptr += nwritten;
            }
            else
            {
                if (nwritten < 0)
                {
                    if (errno == EINTR || errno == EAGAIN)
                    {
                        continue;
                    }
                    else
                    {
                        ret = -5;
                        goto out_error;
                    }
                }
            }
        } while (nread > 0);
    }

    ret = fsync(fd_to);
	if (ret < 0) {
		printf("Sync Failed:%s, file path:%s", strerror(errno), to);
		goto out_error;
	}
	
    if (close(fd_to) < 0)
    {
        fd_to = -1;
        ret = -6;
        goto out_error;
    }
    close(fd_from);

    /* Success! */
    return 0;

out_error:
    printf("copyfile %s to %s error:%d\n", from, to, ret);
    close(fd_from);
    if (fd_to >= 0)
        close(fd_to);

    return ret;
}

int nvrofs2_mount(int rw)
{
    if (rw)
        return zxic_system("/bin/mount -t jffs2 -o rw,sync mtd:nvrofs2 /mnt/nvrofs2");
    else
        return zxic_system("/bin/mount -t jffs2 -o ro mtd:nvrofs2 /mnt/nvrofs2");
}
int nvrofs2_umount(void)
{
    return zxic_system("/bin/umount -f -l /mnt/nvrofs2");
}

unsigned char *bin2hex(const unsigned char *old, const size_t oldlen)
{
    unsigned char *result = (unsigned char *)malloc(oldlen * 2 + 1);
    size_t i, j;
    int b = 0;

    for (i = j = 0; i < oldlen; i++)
    {
        b = old[i] >> 4;
        result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
        b = old[i] & 0xf;
        result[j++] = (char)(87 + b + (((b - 10) >> 31) & -39));
    }
    result[j] = '\0';
    return result;
}

int calc_file_hash(const char *file_in, unsigned char *hash_value)
{
    MD5_CTX ctx;
    unsigned char *buf;
    int offset;
    int fd;
    ssize_t len;
    
    fd = open(file_in, O_RDONLY);
    if (fd < 0)
        return -1;
    buf = malloc(4096);
    if (buf == NULL)
    {
        close(fd);
        return -1;
    }
    MD5_Init(&ctx);
    do
    {
        len = full_read(fd, buf, 4096);
        MD5_Update(&ctx, buf, len);
        if (len < 4096)
            break;
    } while(1);

    MD5_Final(hash_value, &ctx);
    free(buf);
    close(fd);
    return 0;
}

int file_hash(const char *file_in, const char *file_hash)
{
    unsigned char hash_value[16] = {0};
    unsigned char *hash_str;
    int ret;
    ssize_t ret_s;

    ret = calc_file_hash(file_in, hash_value);
    if (ret < 0)
        return -1;
    hash_str = bin2hex(hash_value, 16);
    ret_s = open_write_close(file_hash, hash_str, 32);
    free(hash_str);
    if (ret_s != 32)
        return -1;
    return 0;
}
int file_hash_check(const char *file_in, const char *file_hash)
{
    unsigned char hash_value[16] = {0};
    unsigned char *hash_str;
    unsigned char  hash_str2[33] = {0};
    int ret;
    ssize_t ret_s;

    ret = calc_file_hash(file_in, hash_value);
    if (ret < 0)
        return -1;
    hash_str = bin2hex(hash_value, 16);
    memset(hash_str2, 0, sizeof(hash_str2));
    ret_s = open_read_close(file_hash, hash_str2, 32);
    if (ret_s != 32)
        return -1;
    if (strcmp(hash_str, hash_str2) == 0)
    {
        return 0;
    }
    return -1;
}

unsigned int cpnv_NvroBackup(void)
{
    char mtd_path[MAX_PATH] = {0};
    int ret;

    ret = mtd_find("nvrofs2", mtd_path, DEVICE_MTD_BLOCK, MAX_PATH);
    if (ret < 0)
    {
        printf("[error]cpnv can not find nvrofs2\n");
        return CPNV_ERROR;
    }
    ret = mtd_erase_partition("nvrofs2");
    if (ret != 0)
    {
        printf("[error]cpnv erase nvrofs2\n");
        return CPNV_ERROR;
    }

    ret = nvrofs2_mount(1);
    if (ret != 0)
    {
        nvrofs2_umount();
        ret = nvrofs2_mount(1);
        if (ret != 0)
        {
            printf("[error]cpnv nvrofs2_mount\n");
            return CPNV_ERROR;
        }
    }
    ret = copyfile("/mnt/nvrofs/nvroall.bin", "/mnt/nvrofs2/nvroall.bin");
    if (ret != 0)
    {
        printf("[error]cpnv nvrofs2 copyfile\n");
        goto out_err;
    }
    ret = file_hash("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
    if (ret != 0)
    {
        printf("[error]cpnv file_hash\n");
        goto out_err;
    }
    ret = nvrofs2_umount();
    if (ret < 0)
    {
        printf("[error]cpnv nvrofs2_umount\n");
        return CPNV_ERROR;
    }

    ret = flags_set_nvroflag(NVRO_BACKED_UP);
    if (ret != 0)
    {
        printf("[error]cpnv NVRO_BACKED_UP\n");
        return CPNV_ERROR;
    }
    return CPNV_OK;

out_err:
    nvrofs2_umount();

    return CPNV_ERROR;
}

unsigned int cpnv_NvroRestore(void)
{
    int ret;
    unsigned int ret_u;
    unsigned int nvro_flag;

    nvro_flag = flags_get_nvroflag();
    if (nvro_flag != NVRO_RESTORING)
    {
        printf("[error]cpnv_NvroRestore nvro flag error\n");
        return CPNV_ERROR;
    }
    nvrofs2_umount();
    ret = nvrofs2_mount(0);
    if (ret != 0)
    {
        printf("[error]cpnv nvrofs2_mount\n");
        return CPNV_ERROR;
    }
    ret = file_hash_check("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs2/nvroall.bin.hash");
    if (ret != 0)
    {
        printf("[error]cpnv file_hash_check\n");
        goto out_err;
    }
    ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 1);
    if (ret_u != CPNV_OK)
    {
        printf("[error]cpnv nvrofs Attr 1\n");
        goto out_err;
    }
    ret = copyfile("/mnt/nvrofs2/nvroall.bin", "/mnt/nvrofs/nvroall.bin");
    if (ret != 0)
    {
        printf("[error]cpnv nvrofs2 restore copyfile\n");
        goto out_err;
    }
	ret_u = cpnv_ChangeFsPartitionAttr(FS_NVROFS, 0);
    if (ret_u != CPNV_OK)
    {
        printf("[error]cpnv nvrofs Attr 0\n");
        goto out_err;
    }
    ret = nvrofs2_umount();
    if (ret < 0)
    {
        printf("[error]cpnv nvrofs2_umount\n");
        return CPNV_ERROR;
    }
    ret = flags_set_nvroflag(NVRO_BACKED_UP);
    if (ret != 0)
    {
        printf("[error]cpnv_NvroRestore set NVRO_BACKED_UP\n");
        return CPNV_ERROR;
    }
    return CPNV_OK;

out_err:
    nvrofs2_umount();
    flags_set_nvroflag(NVRO_BACKED_UP);

    return CPNV_ERROR;
}
