/*
 * Copyright (c) 2010, Code Aurora Forum. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above
 *     copyright notice, this list of conditions and the following
 *     disclaimer in the documentation and/or other materials provided
 *     with the distribution.
 *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/reboot.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/mount.h>  // for _IOW, _IOR, mount()

#include "mmcutils.h"

unsigned ext3_count = 0;
char *ext3_partitions[] = {"system", "userdata", "cache", "NONE"};

unsigned vfat_count = 0;
char *vfat_partitions[] = {"modem", "NONE"};

struct MmcPartition {
    char *device_index;
    char *filesystem;
    char *name;
    unsigned dstatus;
    unsigned dtype ;
    unsigned dfirstsec;
    unsigned dsize;
};

typedef struct {
    MmcPartition *partitions;
    int partitions_allocd;
    int partition_count;
} MmcState;

static MmcState g_mmc_state = {
    NULL,   // partitions
    0,      // partitions_allocd
    -1      // partition_count
};

#define MMC_DEVICENAME "/dev/block/mmcblk0"

static void
mmc_partition_name (MmcPartition *mbr, unsigned int type) {
    switch(type)
    {
        char name[64];
        case MMC_BOOT_TYPE:
            sprintf(name,"boot");
            mbr->name = strdup(name);
            break;
        case MMC_RECOVERY_TYPE:
            sprintf(name,"recovery");
            mbr->name = strdup(name);
            break;
        case MMC_EXT3_TYPE:
            if (strcmp("NONE", ext3_partitions[ext3_count])) {
                strcpy((char *)name,(const char *)ext3_partitions[ext3_count]);
                mbr->name = strdup(name);
                ext3_count++;
            }
            mbr->filesystem = strdup("ext3");
            break;
        case MMC_VFAT_TYPE:
            if (strcmp("NONE", vfat_partitions[vfat_count])) {
                strcpy((char *)name,(const char *)vfat_partitions[vfat_count]);
                mbr->name = strdup(name);
                vfat_count++;
            }
            mbr->filesystem = strdup("vfat");
            break;
    };
}

static int
mmc_read_mbr (const char *device, MmcPartition *mbr) {
    FILE *fd;
    unsigned char buffer[512];
    int idx, i;
    unsigned mmc_partition_count = 0;
    unsigned int dtype;
    unsigned int dfirstsec;
    unsigned int EBR_first_sec;
    unsigned int EBR_current_sec;
    int ret = -1;

    fd = fopen(device, "r");
    if(fd == NULL)
    {
        printf("Can't open device: \"%s\"\n", device);
        goto ERROR2;
    }
    if ((fread(buffer, 512, 1, fd)) != 1)
    {
        printf("Can't read device: \"%s\"\n", device);
        goto ERROR1;
    }
    /* Check to see if signature exists */
    if ((buffer[TABLE_SIGNATURE] != 0x55) || \
        (buffer[TABLE_SIGNATURE + 1] != 0xAA))
    {
        printf("Incorrect mbr signatures!\n");
        goto ERROR1;
    }
    idx = TABLE_ENTRY_0;
    for (i = 0; i < 4; i++)
    {
        char device_index[128];

        mbr[mmc_partition_count].dstatus = \
                    buffer[idx + i * TABLE_ENTRY_SIZE + OFFSET_STATUS];
        mbr[mmc_partition_count].dtype   = \
                    buffer[idx + i * TABLE_ENTRY_SIZE + OFFSET_TYPE];
        mbr[mmc_partition_count].dfirstsec = \
                    GET_LWORD_FROM_BYTE(&buffer[idx + \
                                        i * TABLE_ENTRY_SIZE + \
                                        OFFSET_FIRST_SEC]);
        mbr[mmc_partition_count].dsize  = \
                    GET_LWORD_FROM_BYTE(&buffer[idx + \
                                        i * TABLE_ENTRY_SIZE + \
                                        OFFSET_SIZE]);
        dtype  = mbr[mmc_partition_count].dtype;
        dfirstsec = mbr[mmc_partition_count].dfirstsec;
        mmc_partition_name(&mbr[mmc_partition_count], \
                        mbr[mmc_partition_count].dtype);

        sprintf(device_index, "%sp%d", device, (mmc_partition_count+1));
        mbr[mmc_partition_count].device_index = strdup(device_index);

        mmc_partition_count++;
        if (mmc_partition_count == MAX_PARTITIONS)
            goto SUCCESS;
    }

    /* See if the last partition is EBR, if not, parsing is done */
    if (dtype != 0x05)
    {
        goto SUCCESS;
    }

    EBR_first_sec = dfirstsec;
    EBR_current_sec = dfirstsec;

    fseek (fd, (EBR_first_sec * 512), SEEK_SET);
    if ((fread(buffer, 512, 1, fd)) != 1)
        goto ERROR1;

    /* Loop to parse the EBR */
    for (i = 0;; i++)
    {
        char device_index[128];

        if ((buffer[TABLE_SIGNATURE] != 0x55) || (buffer[TABLE_SIGNATURE + 1] != 0xAA))
        {
            break;
        }
        mbr[mmc_partition_count].dstatus = \
                    buffer[TABLE_ENTRY_0 + OFFSET_STATUS];
        mbr[mmc_partition_count].dtype   = \
                    buffer[TABLE_ENTRY_0 + OFFSET_TYPE];
        mbr[mmc_partition_count].dfirstsec = \
                    GET_LWORD_FROM_BYTE(&buffer[TABLE_ENTRY_0 + \
                                        OFFSET_FIRST_SEC])    + \
                                        EBR_current_sec;
        mbr[mmc_partition_count].dsize = \
                    GET_LWORD_FROM_BYTE(&buffer[TABLE_ENTRY_0 + \
                                        OFFSET_SIZE]);
        mmc_partition_name(&mbr[mmc_partition_count], \
                        mbr[mmc_partition_count].dtype);

        sprintf(device_index, "%sp%d", device, (mmc_partition_count+1));
        mbr[mmc_partition_count].device_index = strdup(device_index);

        mmc_partition_count++;
        if (mmc_partition_count == MAX_PARTITIONS)
            goto SUCCESS;

        dfirstsec = GET_LWORD_FROM_BYTE(&buffer[TABLE_ENTRY_1 + OFFSET_FIRST_SEC]);
        if(dfirstsec == 0)
        {
            /* Getting to the end of the EBR tables */
            break;
        }
        /* More EBR to follow - read in the next EBR sector */
        fseek (fd,  ((EBR_first_sec + dfirstsec) * 512), SEEK_SET);
        if ((fread(buffer, 512, 1, fd)) != 1)
            goto ERROR1;

        EBR_current_sec = EBR_first_sec + dfirstsec;
    }

SUCCESS:
    ret = mmc_partition_count;
ERROR1:
    fclose(fd);
ERROR2:
    return ret;
}

int
mmc_scan_partitions() {
    int i;
    ssize_t nbytes;

    if (g_mmc_state.partitions == NULL) {
        const int nump = MAX_PARTITIONS;
        MmcPartition *partitions = malloc(nump * sizeof(*partitions));
        if (partitions == NULL) {
            errno = ENOMEM;
            return -1;
        }
        g_mmc_state.partitions = partitions;
        g_mmc_state.partitions_allocd = nump;
        memset(partitions, 0, nump * sizeof(*partitions));
    }
    g_mmc_state.partition_count = 0;
    ext3_count = 0;
    vfat_count = 0;

    /* Initialize all of the entries to make things easier later.
     * (Lets us handle sparsely-numbered partitions, which
     * may not even be possible.)
     */
    for (i = 0; i < g_mmc_state.partitions_allocd; i++) {
        MmcPartition *p = &g_mmc_state.partitions[i];
        if (p->device_index != NULL) {
            free(p->device_index);
            p->device_index = NULL;
        }
        if (p->name != NULL) {
            free(p->name);
            p->name = NULL;
        }
        if (p->filesystem != NULL) {
            free(p->filesystem);
            p->filesystem = NULL;
        }
    }

    g_mmc_state.partition_count = mmc_read_mbr(MMC_DEVICENAME, g_mmc_state.partitions);
    if(g_mmc_state.partition_count == -1)
    {
        printf("Error in reading mbr!\n");
        // keep "partitions" around so we can free the names on a rescan.
        g_mmc_state.partition_count = -1;
    }
    return g_mmc_state.partition_count;
}

static const MmcPartition *
mmc_find_partition_by_device_index(const char *device_index)
{
    if (g_mmc_state.partitions != NULL) {
        int i;
        for (i = 0; i < g_mmc_state.partitions_allocd; i++) {
            MmcPartition *p = &g_mmc_state.partitions[i];
            if (p->device_index !=NULL && p->name != NULL) {
                if (strcmp(p->device_index, device_index) == 0) {
                    return p;
                }
            }
        }
    }
    return NULL;
}

const MmcPartition *
mmc_find_partition_by_name(const char *name)
{
    if (name[0] == '/') {
        return mmc_find_partition_by_device_index(name);
    }

    if (g_mmc_state.partitions != NULL) {
        int i;
        for (i = 0; i < g_mmc_state.partitions_allocd; i++) {
            MmcPartition *p = &g_mmc_state.partitions[i];
            if (p->device_index !=NULL && p->name != NULL) {
                if (strcmp(p->name, name) == 0) {
                    return p;
                }
            }
        }
    }
    return NULL;
}

#define MKE2FS_BIN      "/sbin/mke2fs"
#define TUNE2FS_BIN     "/sbin/tune2fs"
#define E2FSCK_BIN      "/sbin/e2fsck"

int
run_exec_process ( char **argv) {
    pid_t pid;
    int status;
    pid = fork();
    if (pid == 0) {
        execv(argv[0], argv);
        fprintf(stderr, "E:Can't run (%s)\n",strerror(errno));
        _exit(-1);
    }

    waitpid(pid, &status, 0);
    if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) {
        return 1;
    }
    return 0;
}

int
format_ext3_device (const char *device) {
    char *const mke2fs[] = {MKE2FS_BIN, "-j", "-q", device, NULL};
    char *const tune2fs[] = {TUNE2FS_BIN, "-C", "1", device, NULL};
    // Run mke2fs
    if(run_exec_process(mke2fs)) {
        printf("failure while running mke2fs\n");
        return -1;
    }

    // Run tune2fs
    if(run_exec_process(tune2fs)) {
        printf("failure while running mke2fs\n");
        return -1;
    }

    // Run e2fsck
    char *const e2fsck[] = {E2FSCK_BIN, "-fy", device, NULL};
    if(run_exec_process(e2fsck)) {
        printf("failure while running e2fsck\n");
        return -1;
    }

    return 0;
}

int
format_ext2_device (const char *device) {
    // Run mke2fs
    char *const mke2fs[] = {MKE2FS_BIN, device, NULL};
    if(run_exec_process(mke2fs))
        return -1;

    // Run tune2fs
    char *const tune2fs[] = {TUNE2FS_BIN, "-C", "1", device, NULL};
    if(run_exec_process(tune2fs))
        return -1;

    // Run e2fsck
    char *const e2fsck[] = {E2FSCK_BIN, "-fy", device, NULL};
    if(run_exec_process(e2fsck))
        return -1;

    return 0;
}

int
mmc_format_ext3 (MmcPartition *partition) {
    char device[128];
    strcpy(device, partition->device_index);
    return format_ext3_device(device);
}

int
mmc_mount_partition(const MmcPartition *partition, const char *mount_point,
        int read_only)
{
    const unsigned long flags = MS_NOATIME | MS_NODEV | MS_NODIRATIME;
    char devname[128];
    int rv = -1;
    strcpy(devname, partition->device_index);
    if (partition->filesystem == NULL) {
        printf("Null filesystem!\n");
        return rv;
    }
    if (!read_only) {
        rv = mount(devname, mount_point, partition->filesystem, flags, NULL);
    }
    if (read_only || rv < 0) {
        rv = mount(devname, mount_point, partition->filesystem, flags | MS_RDONLY, 0);
        if (rv < 0) {
            printf("Failed to mount %s on %s: %s\n",
                    devname, mount_point, strerror(errno));
        } else {
            printf("Mount %s on %s read-only\n", devname, mount_point);
        }
    }
    return rv;
}

int
mmc_raw_copy (const MmcPartition *partition, char *in_file) {
    int ch;
    FILE *in;
    FILE *out;
    int val = 0;
    char buf[512];
    unsigned sz = 0;
    unsigned i;
    int ret = -1;
    char *out_file = partition->device_index;

    in  = fopen ( in_file,  "r" );
    if (in == NULL)
        goto ERROR3;

    out = fopen ( out_file,  "w" );
    if (out == NULL)
        goto ERROR2;

    fseek(in, 0L, SEEK_END);
    sz = ftell(in);
    fseek(in, 0L, SEEK_SET);

    if (sz % 512)
    {
        while ( ( ch = fgetc ( in ) ) != EOF )
            fputc ( ch, out );
    }
    else
    {
        for (i=0; i< (sz/512); i++)
        {
            if ((fread(buf, 512, 1, in)) != 1)
                goto ERROR1;
            if ((fwrite(buf, 512, 1, out)) != 1)
                goto ERROR1;
        }
    }

    fsync(fileno(out));
    ret = 0;
ERROR1:
    fclose ( out );
ERROR2:
    fclose ( in );
ERROR3:
    return ret;

}


int
mmc_raw_dump_internal (const char* in_file, const char *out_file) {
    int ch;
    FILE *in;
    FILE *out;
    int val = 0;
    char buf[512];
    unsigned sz = 0;
    unsigned i;
    int ret = -1;

    in  = fopen ( in_file,  "r" );
    if (in == NULL)
        goto ERROR3;

    out = fopen ( out_file,  "w" );
    if (out == NULL)
        goto ERROR2;

    fseek(in, 0L, SEEK_END);
    sz = ftell(in);
    fseek(in, 0L, SEEK_SET);

    if (sz % 512)
    {
        while ( ( ch = fgetc ( in ) ) != EOF )
            fputc ( ch, out );
    }
    else
    {
        for (i=0; i< (sz/512); i++)
        {
            if ((fread(buf, 512, 1, in)) != 1)
                goto ERROR1;
            if ((fwrite(buf, 512, 1, out)) != 1)
                goto ERROR1;
        }
    }

    fsync(fileno(out));
    ret = 0;
ERROR1:
    fclose ( out );
ERROR2:
    fclose ( in );
ERROR3:
    return ret;

}

// TODO: refactor this to not be a giant copy paste mess
int
mmc_raw_dump (const MmcPartition *partition, char *out_file) {
    return mmc_raw_dump_internal(partition->device_index, out_file);
}


int
mmc_raw_read (const MmcPartition *partition, char *data, int data_size) {
    int ch;
    FILE *in;
    int val = 0;
    char buf[512];
    unsigned sz = 0;
    unsigned i;
    int ret = -1;
    char *in_file = partition->device_index;

    in  = fopen ( in_file,  "r" );
    if (in == NULL)
        goto ERROR3;

    fseek(in, 0L, SEEK_END);
    sz = ftell(in);
    fseek(in, 0L, SEEK_SET);

    fread(data, data_size, 1, in);

    ret = 0;
ERROR1:
ERROR2:
    fclose ( in );
ERROR3:
    return ret;

}

int
mmc_raw_write (const MmcPartition *partition, char *data, int data_size) {
    int ch;
    FILE *out;
    int val = 0;
    char buf[512];
    unsigned sz = 0;
    unsigned i;
    int ret = -1;
    char *out_file = partition->device_index;

    out  = fopen ( out_file,  "w" );
    if (out == NULL)
        goto ERROR3;

    fwrite(data, data_size, 1, out);

    ret = 0;
ERROR1:
ERROR2:
    fclose ( out );
ERROR3:
    return ret;

}

int cmd_mmc_restore_raw_partition(const char *partition, const char *filename)
{
    if (partition[0] != '/') {
        mmc_scan_partitions();
        const MmcPartition *p;
        p = mmc_find_partition_by_name(partition);
        if (p == NULL)
            return -1;
        return mmc_raw_copy(p, filename);
    }
    else {
        return mmc_raw_dump_internal(filename, partition);
    }
}

int cmd_mmc_backup_raw_partition(const char *partition, const char *filename)
{
    if (partition[0] != '/') {
        mmc_scan_partitions();
        const MmcPartition *p;
        p = mmc_find_partition_by_name(partition);
        if (p == NULL)
            return -1;
        return mmc_raw_dump(p, filename);
    }
    else {
        return mmc_raw_dump_internal(partition, filename);
    }
}

int cmd_mmc_erase_raw_partition(const char *partition)
{
    return 0;
}

int cmd_mmc_erase_partition(const char *partition, const char *filesystem)
{
    mmc_scan_partitions();
    const MmcPartition *p;
    p = mmc_find_partition_by_name(partition);
    if (p == NULL)
        return -1;
    return mmc_format_ext3 (p);
}

int cmd_mmc_mount_partition(const char *partition, const char *mount_point, const char *filesystem, int read_only)
{
    mmc_scan_partitions();
    const MmcPartition *p;
    p = mmc_find_partition_by_name(partition);
    if (p == NULL)
        return -1;
    return mmc_mount_partition(p, mount_point, read_only);
}

int cmd_mmc_get_partition_device(const char *partition, char *device)
{
    mmc_scan_partitions();
    const MmcPartition *p;
    p = mmc_find_partition_by_name(partition);
    if (p == NULL)
        return -1;
    strcpy(device, p->device_index);
    return 0;
}
