/* Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Tests for firmware display library.
 */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "2sysincludes.h"
#include "2common.h"
#include "2misc.h"
#include "2nvstorage.h"
#include "bmpblk_font.h"
#include "gbb_header.h"
#include "host_common.h"
#include "region.h"
#include "test_common.h"
#include "vboot_common.h"
#include "vboot_display.h"
#include "vboot_kernel.h"
#include "vboot_nvstorage.h"

/* Mock data */
static VbCommonParams cparams;
static uint8_t shared_data[VB_SHARED_DATA_MIN_SIZE];
static VbSharedDataHeader *shared = (VbSharedDataHeader *)shared_data;
static char gbb_data[4096 + sizeof(GoogleBinaryBlockHeader)];
static GoogleBinaryBlockHeader *gbb = (GoogleBinaryBlockHeader *)gbb_data;
static BmpBlockHeader *bhdr;
static char debug_info[4096];
static struct vb2_context ctx;
static uint8_t workbuf[VB2_KERNEL_WORKBUF_RECOMMENDED_SIZE];

/* Reset mock data (for use before each test) */
static void ResetMocks(void)
{
	int gbb_used;

	memset(gbb_data, 0, sizeof(gbb_data));
	gbb->major_version = GBB_MAJOR_VER;
	gbb->minor_version = GBB_MINOR_VER;
	gbb->flags = 0;
	gbb_used = sizeof(GoogleBinaryBlockHeader);

	gbb->hwid_offset = gbb_used;
	strcpy(gbb_data + gbb->hwid_offset, "Test HWID");
	gbb->hwid_size = strlen(gbb_data + gbb->hwid_offset) + 1;
	gbb_used = (gbb_used + gbb->hwid_size + 7) & ~7;

	gbb->bmpfv_offset = gbb_used;
	bhdr = (BmpBlockHeader *)(gbb_data + gbb->bmpfv_offset);
	gbb->bmpfv_size = sizeof(BmpBlockHeader);
	gbb_used = (gbb_used + gbb->bmpfv_size + 7) & ~7;
	memcpy(bhdr->signature, BMPBLOCK_SIGNATURE, BMPBLOCK_SIGNATURE_SIZE);
	bhdr->major_version = BMPBLOCK_MAJOR_VERSION;
	bhdr->minor_version = BMPBLOCK_MINOR_VERSION;
	bhdr->number_of_localizations = 3;

	memset(&cparams, 0, sizeof(cparams));
	cparams.shared_data_size = sizeof(shared_data);
	cparams.shared_data_blob = shared_data;
	cparams.gbb_data = gbb;
	cparams.gbb_size = sizeof(gbb_data);

	/*
	 * Note, VbApiKernelFree() expects this to be allocated by
	 * malloc(), so we cannot just assign it staticly.
	 */
	cparams.gbb = malloc(sizeof(*gbb));
	gbb->header_size = sizeof(*gbb);
	gbb->rootkey_offset = gbb_used;
	gbb->rootkey_size = 64;
	gbb_used += 64;
	gbb->recovery_key_offset = gbb_used;
	gbb->recovery_key_size = 64;
	gbb_used += 64;
	memcpy(cparams.gbb, gbb, sizeof(*gbb));

	memset(&ctx, 0, sizeof(ctx));
	ctx.workbuf = workbuf;
	ctx.workbuf_size = sizeof(workbuf);
	vb2_init_context(&ctx);
	vb2_nv_init(&ctx);

	memset(&shared_data, 0, sizeof(shared_data));
	VbSharedDataInit(shared, sizeof(shared_data));

	*debug_info = 0;
}

/* Mocks */

VbError_t VbExDisplayDebugInfo(const char *info_str)
{
	strncpy(debug_info, info_str, sizeof(debug_info));
	debug_info[sizeof(debug_info) - 1] = '\0';
	return VBERROR_SUCCESS;
}

/* Test displaying debug info */
static void DebugInfoTest(void)
{
	char hwid[VB_REGION_HWID_LEN];
	int i;

	/* Recovery string should be non-null for any code */
	for (i = 0; i < 0x100; i++)
		TEST_PTR_NEQ(RecoveryReasonString(i), NULL, "Non-null reason");

	/* HWID should come from the gbb */
	ResetMocks();
	VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
	TEST_EQ(strcmp(hwid, "Test HWID"), 0, "HWID");
	VbApiKernelFree(&cparams);

	ResetMocks();
	cparams.gbb_size = 0;
	VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
	TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID bad gbb");
	VbApiKernelFree(&cparams);

	ResetMocks();
	cparams.gbb->hwid_size = 0;
	VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
	TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID missing");
	VbApiKernelFree(&cparams);

	ResetMocks();
	cparams.gbb->hwid_offset = cparams.gbb_size + 1;
	VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
	TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID past end");
	VbApiKernelFree(&cparams);

	ResetMocks();
	cparams.gbb->hwid_size = cparams.gbb_size;
	VbRegionReadHWID(&cparams, hwid, sizeof(hwid));
	TEST_EQ(strcmp(hwid, "{INVALID}"), 0, "HWID overflow");
	VbApiKernelFree(&cparams);

	/* Display debug info */
	ResetMocks();
	VbDisplayDebugInfo(&ctx, &cparams);
	TEST_NEQ(*debug_info, '\0', "Some debug info was displayed");
	VbApiKernelFree(&cparams);
}

/* Test localization */
static void LocalizationTest(void)
{
	uint32_t count = 6;

	ResetMocks();
	cparams.gbb->bmpfv_size = 0;
	TEST_EQ(VbGetLocalizationCount(&cparams, &count),
		VBERROR_UNKNOWN, "VbGetLocalizationCount bad gbb");
	TEST_EQ(count, 0, "  count");
	VbApiKernelFree(&cparams);

	ResetMocks();
	bhdr->signature[0] ^= 0x5a;
	TEST_EQ(VbGetLocalizationCount(&cparams, &count),
		VBERROR_UNKNOWN, "VbGetLocalizationCount bad bmpfv");
	VbApiKernelFree(&cparams);

	ResetMocks();
	TEST_EQ(VbGetLocalizationCount(&cparams, &count), 0,
		"VbGetLocalizationCount()");
	TEST_EQ(count, 3, "  count");
	VbApiKernelFree(&cparams);
}

/* Test display key checking */
static void DisplayKeyTest(void)
{
	ResetMocks();
	VbCheckDisplayKey(&ctx, &cparams, 'q');
	TEST_EQ(*debug_info, '\0', "DisplayKey q = does nothing");
	VbApiKernelFree(&cparams);

	ResetMocks();
	VbCheckDisplayKey(&ctx, &cparams, '\t');
	TEST_NEQ(*debug_info, '\0', "DisplayKey tab = display");
	VbApiKernelFree(&cparams);

	/* Toggle localization */
	ResetMocks();
	vb2_nv_set(&ctx, VB2_NV_LOCALIZATION_INDEX, 0);
	VbCheckDisplayKey(&ctx, &cparams, VB_KEY_DOWN);
	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_LOCALIZATION_INDEX), 2,
		"DisplayKey up");
	VbCheckDisplayKey(&ctx, &cparams, VB_KEY_LEFT);
	vb2_nv_get(&ctx, VB2_NV_LOCALIZATION_INDEX);
	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_LOCALIZATION_INDEX), 1,
		"DisplayKey left");
	VbCheckDisplayKey(&ctx, &cparams, VB_KEY_RIGHT);
	vb2_nv_get(&ctx, VB2_NV_LOCALIZATION_INDEX);
	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_LOCALIZATION_INDEX), 2,
		"DisplayKey right");
	VbCheckDisplayKey(&ctx, &cparams, VB_KEY_UP);
	vb2_nv_get(&ctx, VB2_NV_LOCALIZATION_INDEX);
	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_LOCALIZATION_INDEX), 0,
		"DisplayKey up");
	VbApiKernelFree(&cparams);

	/* Reset localization if localization count is invalid */
	ResetMocks();
	vb2_nv_set(&ctx, VB2_NV_LOCALIZATION_INDEX, 1);
	bhdr->signature[0] ^= 0x5a;
	VbCheckDisplayKey(&ctx, &cparams, VB_KEY_UP);
	TEST_EQ(vb2_nv_get(&ctx, VB2_NV_LOCALIZATION_INDEX), 0,
		"DisplayKey invalid");
	VbApiKernelFree(&cparams);
}

static void FontTest(void)
{
	FontArrayHeader h;
	FontArrayEntryHeader eh[3] = {
		{
			.ascii = 'A',
			.info.original_size = 10,
		},
		{
			.ascii = 'B',
			.info.original_size = 20,
		},
		{
			.ascii = 'C',
			.info.original_size = 30,
		},
	};
	FontArrayEntryHeader *eptr;
	uint8_t buf[sizeof(h) + sizeof(eh)];
	VbFont_t *fptr;
	void *bufferptr;
	uint32_t buffersize;

	/* Create font data */
	h.num_entries = ARRAY_SIZE(eh);
	memcpy(buf, &h, sizeof(h));
	eptr = (FontArrayEntryHeader *)(buf + sizeof(h));
	memcpy(eptr, eh, sizeof(eh));

	fptr = VbInternalizeFontData((FontArrayHeader *)buf);
	TEST_PTR_EQ(fptr, buf, "Internalize");

	TEST_PTR_EQ(VbFindFontGlyph(fptr, 'B', &bufferptr, &buffersize),
		    &eptr[1].info, "Glyph found");
	TEST_EQ(buffersize, eptr[1].info.original_size, "  size");
	TEST_PTR_EQ(VbFindFontGlyph(fptr, 'X', &bufferptr, &buffersize),
		    &eptr[0].info, "Glyph not found");
	TEST_EQ(buffersize, eptr[0].info.original_size, "  size");

	/* Test invalid rendering params */
	VbRenderTextAtPos(NULL, 0, 0, 0, fptr);
	VbRenderTextAtPos("ABC", 0, 0, 0, NULL);

	VbDoneWithFontForNow(fptr);

}

int main(void)
{
	DebugInfoTest();
	LocalizationTest();
	DisplayKeyTest();
	FontTest();

	return gTestSuccess ? 0 : 255;
}
