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

#include <common.h>
#include <blk.h>
#include <emmc_storage.h>
#include <emmc_partitions.h>
#include <mmc.h>
#include <part.h>
#include <u-boot/sha256.h>

#include <zircon_uboot/partition.h>
#include <zircon_uboot/util.h>

#define BLK_SIZE (512)
#define GPT_SIZE_LBA (33)
#define GPT_SIZE (GPT_SIZE_LBA * BLK_SIZE)

// `gpt_update_img_t` consists of primary + secondary GPT concatenated together.
typedef struct {
	gpt_header primary_header;
	uint8_t reserved_1[BLK_SIZE - sizeof(gpt_header)];
	gpt_entry primary_entries[GPT_ENTRY_NUMBERS];

	gpt_entry backup_entries[GPT_ENTRY_NUMBERS];
	gpt_header backup_header;
	uint8_t reserved_2[BLK_SIZE - sizeof(gpt_header)];
} __packed gpt_update_img_t;

static gpt_update_img_t gpt_update_img __aligned(ARCH_DMA_MINALIGN);

int gpt_update()
{
	printf("GPT Update: checking for new GPT\n");

	struct mmc *mmc = find_mmc_device(STORAGE_DEV_EMMC);
	if (!mmc) {
		fprintf(stderr, "GPT Update: No MMC device found\n");
		return -1;
	}

	struct blk_desc *blk_desc = mmc_get_blk_desc(mmc);
	if (!blk_desc) {
		fprintf(stderr, "GPT Update: mmc_get_blk_desc failed\n");
		return -1;
	}

	zircon_partition *migration_part = zircon_get_partition("migration");
	if (!migration_part) {
		fprintf(stderr, "GPT Update: partition not found\n");
		return -1;
	}

	if (migration_part->read(migration_part, 0, &gpt_update_img,
				 sizeof(gpt_update_img))) {
		fprintf(stderr, "GPT Update: read failed\n");
		zircon_free_partition(migration_part);
		return -1;
	}

	lbaint_t disk_size_lba = blk_desc->lba;
	lbaint_t last_usable_lba = disk_size_lba - GPT_SIZE_LBA - 1;
	lbaint_t primary_header_lba = 1;
	lbaint_t backup_header_lba = disk_size_lba - 1;

	if (validate_gpt_header(&gpt_update_img.primary_header,
				primary_header_lba, last_usable_lba) ||
	    validate_gpt_entries(&gpt_update_img.primary_header,
				 gpt_update_img.primary_entries) ||
	    validate_gpt_header(&gpt_update_img.backup_header,
				backup_header_lba, last_usable_lba) ||
	    validate_gpt_entries(&gpt_update_img.backup_header,
				 gpt_update_img.backup_entries)) {
		fprintf(stderr, "GPT Update: GPT validation failed\n");
		zircon_free_partition(migration_part);
		return -1;
	}

	zircon_partition *gpt_primary_part =
		zircon_get_partition("gpt_primary");
	if (!gpt_primary_part) {
		fprintf(stderr, "GPT Update: partition not found\n");
		zircon_free_partition(migration_part);
		return -1;
	}

	if (gpt_primary_part->write(gpt_primary_part, 0, &gpt_update_img,
				    GPT_SIZE)) {
		fprintf(stderr, "GPT Update: primary write failed\n");
		zircon_free_partition(migration_part);
		zircon_free_partition(gpt_primary_part);
		return -1;
	}
	zircon_free_partition(gpt_primary_part);

	zircon_partition *gpt_backup_part = zircon_get_partition("gpt_backup");
	if (!gpt_backup_part) {
		fprintf(stderr, "GPT Update: partition not found\n");
		zircon_free_partition(migration_part);
		return -1;
	}

	if (gpt_backup_part->write(gpt_backup_part, 0,
				   &gpt_update_img.backup_entries, GPT_SIZE)) {
		fprintf(stderr, "GPT Update: backup write failed\n");
		zircon_free_partition(migration_part);
		zircon_free_partition(gpt_backup_part);
		return -1;
	}
	zircon_free_partition(gpt_backup_part);

	int ret = migration_part->erase(migration_part);

	zircon_free_partition(migration_part);

	// reinitialize mmc to update the cached partition table.
	mmc_device_init(mmc);

	printf("GPT Update: update complete\n");

	return ret;
}

/*
 * Generate a default serial number of given size (including null terminator)
 * based on the eMMC device info.
 */
int get_default_serial_number(char *sn, size_t size)
{
	if ((sn == NULL) || !size) {
		return -1;
	}

	// Get eMMC device info.
	struct mmc *mmc = find_mmc_device(STORAGE_DEV_EMMC);
	if (!mmc) {
		printf("Cannot find eMMC dev.\n");
		return -1;
	}

	// The eMMC CID contains a serial number. Hash it to get a default serial number for use
	// in case a real one isn't available.
	uint8_t hash[SHA256_DIGEST_SIZE];
	sha256_csum_wd((const uint8_t *)mmc->cid, sizeof(mmc->cid), hash,
		       CHUNKSZ_SHA256);

	int i = SHA256_DIGEST_SIZE - 1;
	/* if |sn| is too small to fit all hash digest, calc how many can be stored */
	if (size < (SHA256_DIGEST_SIZE * 2 + 1)) {
		i = ((size - 1) / 2) - 1;
	}

	static const char hex[] = "0123456789ABCDEF";
	int j = 0;
	for (; i >= 0; i--) {
		sn[j++] = hex[(hash[i] >> 4) & 0xF];
		sn[j++] = hex[hash[i] & 0xF];
	}
	sn[size - 1] = '\0';

	return 0;
}
