/*
 * Copyright (c) 2020 The Fuchsia Authors
 *
 * SPDX-License-Identifier:	BSD-3-Clause
 */

#include <amlogic/storage.h>
#include <common.h>
#include <config.h>
#include <fastboot.h>
#include <image-sparse.h>
#include <zircon/partition.h>

#include "lz4_wrapper.h"

static uint8_t lz4_image_decompress_buffer[4 * 1024 * 1024];

void fb_zircon_sparse_mssg(const char *message, char *response)
{
	/* b/239740938: Use the response string */
	fb_fail(message);
}

static lbaint_t fb_zircon_sparse_write(struct sparse_storage *info,
				       lbaint_t blk, lbaint_t blkcnt,
				       const void *buffer)
{
	zircon_partition *part = (zircon_partition *)info->priv;
	uint64_t offset = blk * info->blksz;
	size_t size = blkcnt * info->blksz;
	return part->write(part, offset, buffer, size) ? 0 : blkcnt;
}

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

static int write_lz4_compressed_image(zircon_partition *part,
				      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\n");

	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 ((ret = part->write(part, write_offset,
				       lz4_image_decompress_buffer,
				       decompressed_size))) {
			printf("Failed to write to storage\n");
			return -1;
		}
		write_offset += decompressed_size;
	}
	return 0;
}

void fb_zircon_flash_write(const char *part_name, void *download_buffer,
			   unsigned int download_bytes)
{
	// `write_sparse_image` sets fb_fail() on error, so start with
	// fb_okay() to avoid clobbering the return value.
	fb_okay(NULL);

	zircon_partition *part = zircon_get_fastboot_partition(part_name);
	if (!part) {
		fb_fail("partition not found");
		return;
	}

	if (!part->write) {
		zircon_free_partition(part);
		fb_fail("Device must be unlocked to run this command");
		return;
	}

	printf("Flashing '%s'\n", part_name);
	if (is_sparse_image(download_buffer)) {
		struct sparse_storage sparse = {
			.blksz = 1,
			.start = 0,
			.size = part->size,
			.priv = (void *)part,
			.write = fb_zircon_sparse_write,
			.reserve = fb_zircon_sparse_reserve,
			.mssg = fb_zircon_sparse_mssg,
		};

		printf("sparse image detected\n");
		if (write_sparse_image(&sparse, part_name, download_buffer,
				       download_bytes, "")) {
			// The mssg function will be called by write_sparse_image on failure,
			// so no need to call fb_fail here.
			printf("sparse image write failed\n");
		}
	} else {
		if (is_data_lz4_compressed(download_buffer, download_bytes)) {
			printf("lz4 flat image detected\n");

			if ((write_lz4_compressed_image(part, download_buffer,
							download_bytes))) {
				fb_fail("failed to write image");
			}
		} else {
			printf("uncompressed flat image detected\n");
			if (part->write(part, 0, download_buffer,
					download_bytes)) {
				fb_fail("failed to write image");
			}
		}
	}
	printf("Flashing '%s' done\n", part_name);
	zircon_free_partition(part);
}

void fb_zircon_erase(const char *part_name)
{
	zircon_partition *part = zircon_get_fastboot_partition(part_name);
	if (!part) {
		fb_fail("partition not found");
		return;
	}

	if (!part->erase) {
		zircon_free_partition(part);
		fb_fail("Device must be unlocked to run this command");
		return;
	}

	printf("Erasing '%s'\n", part_name);

	if (part->erase(part)) {
		printf("partition erase failed: %s\n", part_name);
		fb_fail("failed erasing from device");
	} else {
		fb_okay(NULL);
	}

	zircon_free_partition(part);
}
