/*
 * Copyright (C) 2016 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:     GPL-2.0+
 */

#include <common.h>
#include <stdlib.h>
#include <linux/string.h>
#include <fsl_fastboot.h>
#include <fsl_avb.h>

/* as libavb's bootctl doesn't have the get_var support
 * we add the getvar support on our side ...*/
#ifndef MAX_PTN
#define MAX_PTN 32
#endif
#define SLOT_NUM 2
static char *slot_suffix[SLOT_NUM] = {"_a", "_b"};

static int strcmp_l1(const char *s1, const char *s2) {
	if (!s1 || !s2)
		return -1;
	return strncmp(s1, s2, strlen(s1));
}

static bool slot_is_bootable(AvbABSlotData* slot) {
#ifdef CONFIG_DUAL_BOOTLOADER
  /* The 'bootloader_verified' will be set when the slot has only one chance
   * left, which means the slot is bootable even tries_remaining is 0.
   */
  return slot->priority > 0 &&
         (slot->successful_boot || (slot->tries_remaining > 0)
         || (slot->bootloader_verified == 1));
#else
  return slot->priority > 0 &&
         (slot->successful_boot || (slot->tries_remaining > 0));
#endif
}

int slotidx_from_suffix(char *suffix) {
	int slot = -1;

	if (!strcmp(suffix, "_a") ||
			!strcmp(suffix, "a"))
		slot = 0;
	else if (!strcmp(suffix, "_b") ||
			!strcmp(suffix, "b"))
		slot = 1;

	return slot;
}

bool is_slotvar_avb(char *cmd) {

	assert(cmd != NULL);
	if (!strcmp_l1("has-slot:", cmd) ||
		!strcmp_l1("slot-successful:", cmd) ||
		!strcmp_l1("slot-count", cmd) ||
		!strcmp_l1("slot-suffixes", cmd) ||
		!strcmp_l1("current-slot", cmd) ||
		!strcmp_l1("slot-unbootable:", cmd) ||
		!strcmp_l1("slot-retry-count:", cmd))
		return true;
	return false;
}

int get_curr_slot(AvbABData *ab_data) {
	if (slot_is_bootable(&ab_data->slots[0]) &&
		slot_is_bootable(&ab_data->slots[1])) {
		if (ab_data->slots[1].priority > ab_data->slots[0].priority)
			return 1;
		else
			return 0;
	} else if (slot_is_bootable(&ab_data->slots[0]))
		return 0;
	else if (slot_is_bootable(&ab_data->slots[1]))
		return 1;
	else
		return -1;
}

extern struct fastboot_ptentry g_ptable[MAX_PTN];
extern unsigned int g_pcount;

static bool has_slot(char *cmd) {
	unsigned int n;
	char *ptr;

	for (n = 0; n < g_pcount; n++) {
		ptr = strstr(g_ptable[n].name, cmd);
		if (ptr != NULL) {
			ptr += strlen(cmd);
			if (!strcmp(ptr, "_a") || !strcmp(ptr, "_b"))
				return true;
		}
	}
	return false;
}

int get_slotvar_avb(AvbABOps *ab_ops, char *cmd, char *buffer, size_t size) {

	AvbABData ab_data;
	AvbABSlotData *slot_data;
	int slot;

	if ((ab_ops == NULL) || (cmd == NULL) || (buffer == NULL))
		return -1;

	char *str = cmd;
	if (!strcmp_l1("has-slot:", cmd)) {
		str += strlen("has-slot:");
		if (has_slot(str))
			strlcpy(buffer, "yes", size);
		else
			strlcpy(buffer, "no", size);
		return 0;

	} else if (!strcmp_l1("slot-suffixes", cmd)) {
		strlcpy(buffer, "_a,_b", size);
		return 0 ;

	} else if (!strcmp_l1("slot-count", cmd)) {
		strlcpy(buffer, "2", size);
		return 0 ;
	}

	/* load ab meta */
	if (ab_ops->read_ab_metadata == NULL ||
			ab_ops->read_ab_metadata(ab_ops, &ab_data) != AVB_IO_RESULT_OK) {
		strlcpy(buffer, "ab data read error", size);
		return -1 ;
	}

	if (!strcmp_l1("current-slot", cmd)) {
		int curr = get_curr_slot(&ab_data);
		if (curr >= 0 && curr < SLOT_NUM)
			strlcpy(buffer, slot_suffix[curr] + sizeof(unsigned char), size);
		else {
			strlcpy(buffer, "no bootable slot", size);
			return -1;
		}

	} else if (!strcmp_l1("slot-successful:", cmd)) {
		str += strlen("slot-successful:");
		slot = slotidx_from_suffix(str);
		if (slot < 0) {
			strlcpy(buffer, "no such slot", size);
			return -1;
		} else {
			slot_data = &ab_data.slots[slot];
			bool succ = (slot_data->successful_boot != 0);
			strlcpy(buffer, succ ? "yes" : "no", size);
		}

	} else if (!strcmp_l1("slot-unbootable:", cmd)) {
		str += strlen("slot-unbootable:");
		slot = slotidx_from_suffix(str);
		if (slot < 0) {
			strlcpy(buffer, "no such slot", size);
			return -1;
		} else {
			slot_data = &ab_data.slots[slot];
			bool bootable = slot_is_bootable(slot_data);
			strlcpy(buffer, bootable ? "no" : "yes", size);
		}

	} else if (!strcmp_l1("slot-retry-count:", cmd)) {
		str += strlen("slot-retry-count:");
		slot = slotidx_from_suffix(str);
		if (slot < 0) {
			strlcpy(buffer, "no such slot", size);
			return -1;
		}
		else {
			slot_data = &ab_data.slots[slot];
			char var[7];
			sprintf(var, "%d",
				slot_data->tries_remaining);
			strlcpy(buffer, var, size);
		}

	} else {
		strlcpy(buffer, "no such slot command", size);
		return -1;
	}

	return 0;
}

char *select_slot(AvbABOps *ab_ops) {
	AvbABData ab_data;
	int curr;

	if (ab_ops == NULL) {
		return NULL;
	}

	/* load ab meta */
	if (ab_ops->read_ab_metadata == NULL ||
			ab_ops->read_ab_metadata(ab_ops, &ab_data) != AVB_IO_RESULT_OK) {
		return NULL;
	}
	curr = get_curr_slot(&ab_data);
	if (curr >= 0 && curr < SLOT_NUM)
		return slot_suffix[curr];
	else
		return NULL;
}
