#include "io.h"
#include "string.h"
#include "debug.h"
#include "util.h"

#include "flash_adaptor.h"

#include "uuid.h"
#include "gpt.h"

#include "load_gpt.h"

#define SDIO_BLK_SIZE    512

#define CRC32_SIZE      (4)
extern unsigned int crc32(unsigned int crc, unsigned char *buf, unsigned int len);

/*version table*/
#define MAX_GPT_ENTRY 128

typedef struct {
	int num;
	struct gpt_ent entry[MAX_GPT_ENTRY];
}gpt_table_t;
static gpt_table_t gptes;
/*version table end*/

static void dump_gpt_entry(struct gpt_ent * gpte)
{
	INFO("%s: start=%d, end=%d\n", gpte->ent_name, gpte->ent_lba_start, gpte->ent_lba_end);
}

void dump_gpt_table(void)
{
	int i = 0;
	for(i = 0; i < gptes.num; i++) {
		INFO("[%02d,sd%02d] ", i, i);
		dump_gpt_entry(&(gptes.entry[i]));
	}
}

int parse_gpt_table(struct gpt_hdr * hdr, struct gpt_ent * entry)
{
	unsigned int i;

	gptes.num = 0;
	for(i = 0;i < hdr->hdr_entries; i++) {

		memcpy(&(gptes.entry[i]), &entry[i], sizeof(struct gpt_ent));
		gptes.num ++;
	}
	return 0;
}

static unsigned get_aligned(unsigned address, unsigned page_size) {
	return (address + page_size - 1) / page_size * page_size;
}

#define START_ADDR_GPT 0x0 //start from MBR
#define GPT_PRI_READ_SIZE 0x6800  //26k (MBR 512B; GPT HEADER 512B; GPT TABLE 16K; RESERVE 1K; SIGN 8K)
#define GPT_ALT_READ_SIZE 0x4200  // 16.5K

int get_gpt(void * tbuff)
{
	//we need a buff that is at least 64bytes aligned address because of the DMA of EMMC
	unsigned char * buff = (unsigned char *)(uintmax_t)get_aligned((unsigned)(uintmax_t)tbuff, 64);
	int ret = 0;
	long long start = START_ADDR_GPT;
	struct gpt_hdr * hdr = NULL;
	struct gpt_ent * entry = NULL;
	//unsigned char * signature = NULL;

//primary_gpt:
	//emmc only now
	if(read_flash_from_part(0, start, GPT_PRI_READ_SIZE, buff) != 0) {
		ERR("read primary gpt error\n");
		goto alt_gpt;
	}
	hdr = (struct gpt_hdr *)(buff + 512);
	entry = (struct gpt_ent *)(buff + 1024);

	//crc verification

	//signature = buff + 0x4800;
	//FIXME: verify will be implemented later

	goto gpt_load_done;
alt_gpt:
	start = get_flash_capacity() - GPT_ALT_READ_SIZE;//at the last 16.5K of emmc user area

	if(read_flash_from_part(0, start, GPT_ALT_READ_SIZE, buff) != 0) {
		ERR("read alt gpt error\n");
		goto gpt_err;
	}
	hdr = (struct gpt_hdr *)(buff + 0x4000);
	entry = (struct gpt_ent *)(buff);
	//crc verification

	//FIXME: read signature(offset 1MB - 8KB)
	/*
	start = 0x100000 - 0x2000;
	if(read_flash_from_part(0, start, 0x2000, (buff + 0x4800)) != 0) {
		ERR("read alt gpt error\n");
		goto gpt_err;
	}
	*/

	//FIXME: verify will be implemented later

gpt_load_done:
	ret = parse_gpt_table(hdr, entry);

	if(ret != 0) {
		ERR("parse partiton info error\n");
	}
	return 0;

gpt_err:
	ERR("both primary and alt gpt are wrong!\n");
	return FLASH_OP_ERR;
}

static void gpt_convert_efi_name_to_char(char *s, const uint16_t *ent_name, int n)
{
	const char *ent_name_tmp = (const char *)ent_name;
	unsigned char index = 0x00;

	memset((void *)s, 0x00, n);

	for(index = 0; (index<<1) < n; index++) {
		s[index] = ent_name_tmp[index<<1];

		if(!s[index])
			break;
	}

	return;
}

int get_partition_info(void * tbuff)
{
	int ret;

	ret = get_gpt(tbuff);
	if(ret != 0) {
		return -1;
	}

	return 0;
}

int find_partition(const char * name)
{
	int i = 0;
	char ent_name_char[72] = {0};

	for(i = 0; i < gptes.num; i++) {
		//avoid boot = bootloader, boot = bootlogo
		gpt_convert_efi_name_to_char(ent_name_char, gptes.entry[i].ent_name, sizeof(gptes.entry[i].ent_name));
		if(strlen(name) != strlen(ent_name_char))
			continue;
		if(memcmp(name, ent_name_char, strlen(name)) == 0) {
			return i;
		}
	}

	return PARTITION_NOT_EXIST;
}


int fetch_partition_info(int num, struct gpt_ent *gpte)
{
	if((num >= 0) && (num < gptes.num)) {
		memcpy(gpte, &(gptes.entry[num]), sizeof(struct gpt_ent));
		return num;
	}
	return PARTITION_NOT_EXIST;
}

unsigned int get_gpt_entry_number()
{
	return gptes.num;
}

long long read_image(struct gpt_ent *gpte, unsigned int image_size, unsigned char *image_buff)
{
	return read_image_from_offset(gpte, 0, image_size, image_buff);
}

long long read_image_by_ptname(const char *module_name, unsigned int image_size, unsigned char *image_buff)
{
	struct gpt_ent gpte;
	int ret = find_partition(module_name);
	if(ret < 0) {
		return ret;
	}
	fetch_partition_info(ret, &gpte);

	return read_image(&gpte, image_size, image_buff);
}

long long read_image_from_offset(struct gpt_ent *gpte, unsigned int pt_offset, unsigned int size, unsigned char *image_buf)
{
	long long start = 0, end = 0;

	start = gpte->ent_lba_start;
	start *= SDIO_BLK_SIZE;
	start += pt_offset;
	end = gpte->ent_lba_end;
	end *= SDIO_BLK_SIZE;

	//image_size must not exceed the current partition
	if((start + size) > end) {
		ERR("the image is exceed the partition(%x > %x). Possible hacker attack detected!\n",
			(start + size), end);
		return -1;
	}

	//For EMMC:switch to user area
	//For nand and nor: nothing
	switch_flash_part(0);

	return read_flash(start, size, image_buf);
}
