/*
 * Copyright 2014 Broadcom Corporation.
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <config.h>
#include <common.h>
#include <emmc_partitions.h>
#include <fb_mmc.h>
#include <part.h>
#include <aboot.h>
#include <sparse_format.h>
#include <mmc.h>
#include <fb_fastboot.h>
#include <amlogic/aml_mmc.h>
#include <amlogic/storage_if.h>
#include <lz4_wrapper.h>

#ifndef CONFIG_FASTBOOT_GPT_NAME
#define CONFIG_FASTBOOT_GPT_NAME GPT_ENTRY_NAME
#endif

#ifndef CONFIG_FASTBOOT_MBR_NAME
#define CONFIG_FASTBOOT_MBR_NAME "mbr"
#endif


/* The 64 defined bytes plus the '\0' */
struct fb_mmc_sparse {
	block_dev_desc_t	*dev_desc;
};
#ifdef CONFIG_EFI_PARTITION
static int part_get_info_efi_by_name_or_alias(block_dev_desc_t *dev_desc,
		const char *name, disk_partition_t *info)
{
	int ret;

	ret = get_partition_info_efi_by_name(dev_desc, name, info);
	if (ret) {
		/* strlen("fastboot_partition_alias_") + 32(part_name) + 1 */
		char env_alias_name[25 + 32 + 1];
		char *aliased_part_name;

		/* check for alias */
		strcpy(env_alias_name, "fastboot_partition_alias_");
		strncat(env_alias_name, name, 32);
		aliased_part_name = getenv(env_alias_name);
		if (aliased_part_name != NULL)
			ret = get_partition_info_efi_by_name(dev_desc,
					aliased_part_name, info);
	}
	return ret;
}
#endif

static lbaint_t fb_mmc_sparse_write(struct sparse_storage *info,
		lbaint_t blk, lbaint_t blkcnt, const void *buffer)
{
	struct fb_mmc_sparse *sparse = info->priv;
	block_dev_desc_t *dev_desc = sparse->dev_desc;

	return dev_desc->block_write(dev_desc->dev, blk, blkcnt,
				     buffer);
}

static lbaint_t fb_mmc_sparse_reserve(struct sparse_storage *info,
		lbaint_t blk, lbaint_t blkcnt)
{
	return blkcnt;
}

static void write_raw_image(block_dev_desc_t *dev_desc, disk_partition_t *info,
		const char *part_name, void *buffer,
		unsigned int download_bytes)
{
	lbaint_t blkcnt;
	lbaint_t blks;

	/* determine number of blocks to write */
	blkcnt = ((download_bytes + (info->blksz - 1)) & ~(info->blksz - 1));
	blkcnt = blkcnt / info->blksz;

	if (blkcnt > info->size) {
		error("too large for partition: '%s'\n", part_name);
		fastboot_fail("too large for partition");
		return;
	}

	puts("Flashing Raw Image\n");

	blks = dev_desc->block_write(dev_desc->dev, info->start, blkcnt,
				     buffer);
	if (blks != blkcnt) {
		error("failed writing to device %d\n", dev_desc->dev);
		fastboot_fail("failed writing to device");
		return;
	}

	printf("........ wrote " LBAFU " bytes to '%s'\n", blkcnt * info->blksz,
	       part_name);
	fastboot_okay("");
}

// The maximum decompressed block size for lz4 is 4MB.
static uint8_t lz4_image_decompress_buffer[4 * 1024 * 1024];

static int write_lz4_compressed_image(disk_partition_t *info,
				      const char *part_name,
				      void *download_buffer,
				      unsigned int download_bytes)
{
	int ret = 0;
	struct lz4_frame_header lz4_header;
	size_t lz4_data_offset;
	if ((ret = check_and_extract_lz4_frame_header(
		     download_buffer, download_bytes, &lz4_header,
		     &lz4_data_offset))) {
		printf("Failed to extract lz4 frame header\n");
		return -1;
	}

	const uint8_t *compressed_end = download_buffer + download_bytes;
	const uint8_t *compressed_curr =
		(uint8_t *)download_buffer + lz4_data_offset;

	printf("Flashing lz4 compressed image to partition %s\n", part_name);

	size_t write_offset = 0;
	bool has_more_data = true;
	while (has_more_data) {
		size_t decompressed_size = sizeof(lz4_image_decompress_buffer);
		size_t compressed_size = compressed_end - compressed_curr;
		if ((ret = lz4_decompress(
			     &lz4_header, compressed_curr, &compressed_size,
			     lz4_image_decompress_buffer, &decompressed_size,
			     &has_more_data))) {
			printf("Failed to decompress, %d\n", ret);
			return -1;
		}
		compressed_curr += compressed_size;

		if ((decompressed_size % info->blksz) && has_more_data) {
			printf("Decompressed size %zu is not a multiple of "
			       "partition block size %lu\n",
			       decompressed_size, info->blksz);
			return -1;
		}

		if (store_write_ops((unsigned char *)part_name,
				    lz4_image_decompress_buffer, write_offset,
				    decompressed_size)) {
			printf("Failed to write to storage\n");
			return -1;
		}
		write_offset += decompressed_size;
	}
	return 0;
}

/* erase or flash, when buffer is not NULL, it's write */
static void fb_mmc_bootloader_ops(const char *cmd,
			block_dev_desc_t *dev_desc, void *buffer,
			unsigned int bytes)
{
	char *delim = "-";
	char *hwpart;
	int map = 0, ret = 0;
	char *scmd = (char *) cmd;
	char *ops[] = {"erase", "write"};

	hwpart = strchr(scmd, (int)*delim);

    if (!hwpart) {
		map = AML_BL_BOOT0 | AML_BL_BOOT1;
	} else if (!strcmp(hwpart, "-boot0")) {
		map = AML_BL_BOOT0;
	} else if (!strcmp(hwpart, "-boot1")) {
		map = AML_BL_BOOT1;
	}
    if (map) {
		if (buffer)
            ret = amlmmc_write_bootloader(CONFIG_FASTBOOT_FLASH_MMC_DEV, map,
				bytes, buffer);
        else
			ret = amlmmc_erase_bootloader(CONFIG_FASTBOOT_FLASH_MMC_DEV, map);
		if (ret) {
			error("failed %s %s from device %d", (buffer? ops[1]: ops[0]),
				cmd, dev_desc->dev);
			fastboot_fail("failed bootloader operating to device");
			return;
		}
		printf("........ %s  %s\n", (buffer? ops[1]: ops[0]), cmd);
		fastboot_okay("");
	} else
		fastboot_fail("failed opearting from device");
	return;
}

/**
 * write bootloader on user/boot0/boot1
 * according to bootloader name.
 */
static void fb_mmc_write_bootloader(const char *cmd,
		block_dev_desc_t *dev_desc, void *buffer, unsigned int bytes)
{
	return fb_mmc_bootloader_ops(cmd, dev_desc, buffer, bytes);
}

/**
 * erase bootloader on user/boot0/boot1
 * according to bootloader name.
 */
static void fb_mmc_erase_bootloader(const char *cmd, block_dev_desc_t *dev_desc)
{
	return fb_mmc_bootloader_ops(cmd, dev_desc, NULL, 0);
}

const char *partitions_override_gpt[] = {
	MMC_BOOT_NAME,
	MMC_BOOT_NAME0,
	MMC_BOOT_NAME1,
	MMC_DTB_NAME,
};

bool is_partition_override_gpt(const char *part)
{
	for (size_t i = 0; i < ARRAY_SIZE(partitions_override_gpt); i++) {
		if (strcmp(part, partitions_override_gpt[i]) == 0) {
			return true;
		}
	}
	return false;
}

void fb_mmc_flash_write(const char *cmd, void *download_buffer,
			unsigned int download_bytes)
{
	block_dev_desc_t *dev_desc;
	disk_partition_t info;
	int ret = 0;
	dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
	if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
		error("invalid mmc device\n");
		fastboot_fail("invalid mmc device");
		return;
	}
#ifdef CONFIG_EFI_PARTITION
	if (dev_desc->part_type == PART_TYPE_EFI) {
		if (strcmp(cmd, CONFIG_FASTBOOT_GPT_NAME) == 0) {
			printf("%s: updating MBR, Primary and Backup GPT(s)\n",
			       __func__);
			if (is_valid_gpt_buf(dev_desc, download_buffer)) {
				printf("%s: invalid GPT - refusing to write to flash\n",
				       __func__);
				fastboot_fail("invalid GPT partition");
				return;
			}
			if (write_mbr_and_gpt_partitions(dev_desc, download_buffer)) {
				printf("%s: writing GPT partitions failed\n", __func__);
				fastboot_fail("writing GPT partitions failed");
				return;
			}
			printf("........ success\n");
			fastboot_okay("");
			return;
		} else if (!is_partition_override_gpt(cmd) &&
			   get_partition_info_efi_by_name(dev_desc, cmd,
							  &info)) {
			error("cannot find partition: '%s'\n", cmd);
			fastboot_fail("cannot find partition");
			return;
		}
	}
#endif

#ifdef CONFIG_AML_PARTITION
	if ((dev_desc->part_type == PART_TYPE_AML)
		|| (dev_desc->part_type == PART_TYPE_DOS)
		|| (!strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME))) {
		if (strcmp(cmd, CONFIG_FASTBOOT_MBR_NAME) == 0) {
			printf("%s: updating MBR\n", __func__);
			ret = emmc_update_mbr(download_buffer);
			if (ret)
				fastboot_fail("fastboot update mbr fail");
			else
				fastboot_okay("");
			return;
		}
		if (get_partition_info_aml_by_name(dev_desc, cmd, &info)) {
			error("cannot find partition: '%s'\n", cmd);
			fastboot_fail("cannot find partition");
			return;
		}
	}
#endif
	if (strcmp(cmd, "dtb") == 0) {
#ifndef DTB_BIND_KERNEL
		ret = dtb_write(download_buffer);
		if (ret)
			fastboot_fail("fastboot write dtb fail");
		else {
			/* renew partition table @ once*/
			if (renew_partition_tbl(download_buffer))
				fastboot_fail("fastboot write dtb fail");
			fastboot_okay("");
		}
#else
	fastboot_fail("dtb is bind in kernel, return");
#endif
	} else if (!strncmp(cmd, "bootloader", strlen("bootloader"))) {
		fb_mmc_write_bootloader(cmd, dev_desc, download_buffer, download_bytes);
		return;
	} else {
		if (is_sparse_image(download_buffer)) {
			struct fb_mmc_sparse sparse_priv;
			struct sparse_storage sparse;

			sparse_priv.dev_desc = dev_desc;

			sparse.blksz = info.blksz;
			sparse.start = info.start;
			sparse.size = info.size;
			sparse.write = fb_mmc_sparse_write;
			sparse.reserve = fb_mmc_sparse_reserve;

			printf("Flashing sparse image at offset " LBAFU "\n",
			       sparse.start);
			sparse.priv = &sparse_priv;
			write_sparse_image(&sparse, cmd, download_buffer,
					   download_bytes);
		} else if (is_data_lz4_compressed(download_buffer, download_bytes)) {
			if ((write_lz4_compressed_image(&info, cmd,
							download_buffer,
							download_bytes))) {
				fastboot_fail(
					"failed to write lz4 compressed image");
			}
			fastboot_okay("");
		} else
			write_raw_image(dev_desc, &info, cmd, download_buffer,
					download_bytes);
	}
}

inline lbaint_t lba_max(lbaint_t a, lbaint_t b)
{
	return a > b ? a : b;
}

void fb_mmc_erase_write(const char *cmd, void *download_buffer)
{
	int ret = 0;
	block_dev_desc_t *dev_desc;
	disk_partition_t info;
	lbaint_t blks, blks_start, blks_size, grp_size;
	struct mmc *mmc = find_mmc_device(CONFIG_FASTBOOT_FLASH_MMC_DEV);

	if (mmc == NULL) {
		error("invalid mmc device");
		fastboot_fail("invalid mmc device");
		return;
	}

	dev_desc = get_dev("mmc", CONFIG_FASTBOOT_FLASH_MMC_DEV);
	if (!dev_desc || dev_desc->type == DEV_TYPE_UNKNOWN) {
		error("invalid mmc device");
		fastboot_fail("invalid mmc device");
		return;
	}
#ifdef CONFIG_EFI_PARTITION
	if (dev_desc->part_type == PART_TYPE_EFI &&
	    !is_partition_override_gpt(cmd))
		ret = part_get_info_efi_by_name_or_alias(dev_desc, cmd, &info);
#endif
#ifdef CONFIG_AML_PARTITION
	if ((dev_desc->part_type == PART_TYPE_AML)
		|| (dev_desc->part_type == PART_TYPE_DOS))
		ret = get_partition_info_aml_by_name(dev_desc, cmd, &info);
#endif
	if (ret) {
		error("cannot find partition: '%s'", cmd);
		fastboot_fail("cannot find partition");
		return;
	}
	/* special operation for bootloader */
	if (!strncmp(cmd, "bootloader", strlen("bootloader"))) {
		fb_mmc_erase_bootloader(cmd, dev_desc);
		return;
	} else {
		/* Align blocks to erase group size to avoid erasing other partitions */
		grp_size = mmc->erase_grp_size;
		blks_start = (info.start + grp_size - 1) & ~(grp_size - 1);
		if (info.size >= grp_size)
			blks_size = (info.size - (blks_start - info.start)) &
				    (~(grp_size - 1));
		else
			blks_size = 0;

		lbaint_t unaligned_header_blks =
			(info.start + info.size >= blks_start) ?
				blks_start - info.start :
				info.size;
		lbaint_t unaligned_footer_blks =
			info.size - blks_size - unaligned_header_blks;
		lbaint_t unaligned_buffer_blks =
			lba_max(unaligned_header_blks, unaligned_footer_blks);
		if (unaligned_buffer_blks) {
			size_t unaligned_buffer_size_bytes =
				unaligned_buffer_blks * info.blksz;
			void *unaligned_write_buffer =
				calloc(1, unaligned_buffer_size_bytes);
			if (unaligned_header_blks) {
				printf("%s: writing zeroes to unaligned header starting at %lu for %lu blocks\n",
				       __func__, info.start,
				       unaligned_header_blks);
				blks = dev_desc->block_write(
					dev_desc->dev, info.start,
					unaligned_header_blks,
					unaligned_write_buffer);
				if (blks != unaligned_header_blks) {
					printf("%s: unaligned header write failed\n",
					       __func__);
				}
			}
			if (unaligned_footer_blks) {
				lbaint_t footer_start = blks_start + blks_size;
				printf("%s: writing zeroes to unaligned footer starting at %lu for %lu blocks\n",
				       __func__, footer_start,
				       unaligned_footer_blks);
				blks = dev_desc->block_write(
					dev_desc->dev, footer_start,
					unaligned_footer_blks,
					unaligned_write_buffer);
				if (blks != unaligned_footer_blks) {
					printf("%s: unaligned footer write failed\n",
					       __func__);
				}
			}
			free(unaligned_write_buffer);
		}

		printf("Erasing blocks " LBAFU " to " LBAFU
		       " due to alignment\n",
		       blks_start, blks_start + blks_size);
		blks = dev_desc->block_erase(dev_desc->dev, blks_start,
					     blks_size);
		if (blks != 0) {
			error("failed erasing from device %d", dev_desc->dev);
			fastboot_fail("failed erasing from device");
			return;
		}

		printf("........ erased " LBAFU " bytes from '%s'\n",
		       blks_size * info.blksz, cmd);
		fastboot_okay("");

	}
}
