/*
 * Copyright 2018 The Hafnium Authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "hf/arch/vm/power_mgmt.h"

#include "hf/boot_params.h"
#include "hf/fdt_handler.h"
#include "hf/memiter.h"
#include "hf/std.h"

#include "hftest_common.h"
#include "test/hftest.h"

HFTEST_ENABLE();

static struct hftest_test hftest_constructed[HFTEST_MAX_TESTS];
static size_t hftest_count;
static struct hftest_test *hftest_list;

static struct hftest_context global_context;

struct hftest_context *hftest_get_context(void)
{
	return &global_context;
}

/**
 * Adds the given test information to the global list, to be used by
 * `hftest_use_registered_list`.
 */
void hftest_register(struct hftest_test test)
{
	if (hftest_count < HFTEST_MAX_TESTS) {
		hftest_constructed[hftest_count++] = test;
	} else {
		HFTEST_FAIL(true, "Too many tests");
	}
}

/**
 * Uses the list of tests registered by `hftest_register(...)` as the ones to
 * run.
 */
void hftest_use_registered_list(void)
{
	hftest_list = hftest_constructed;
}

/**
 * Uses the given list of tests as the ones to run.
 */
void hftest_use_list(struct hftest_test list[], size_t count)
{
	hftest_list = list;
	hftest_count = count;
}

/**
 * Writes out a JSON structure describing the available tests.
 */
void hftest_json(void)
{
	const char *suite = NULL;
	size_t i;
	size_t suites_in_image = 0;
	size_t tests_in_suite = 0;

	HFTEST_LOG("{");
	HFTEST_LOG("  \"suites\": [");
	for (i = 0; i < hftest_count; ++i) {
		struct hftest_test *test = &hftest_list[i];
		if (test->suite != suite) {
			/* Close out previously open suite. */
			if (tests_in_suite) {
				HFTEST_LOG("      ]");
				HFTEST_LOG("    },");
			}
			/* Move onto new suite. */
			++suites_in_image;
			suite = test->suite;
			tests_in_suite = 0;
			HFTEST_LOG("    {");
			HFTEST_LOG("      \"name\": \"%s\",", test->suite);
		}
		if (test->kind == HFTEST_KIND_SET_UP) {
			HFTEST_LOG("      \"setup\": true,");
		}
		if (test->kind == HFTEST_KIND_TEAR_DOWN) {
			HFTEST_LOG("      \"teardown\": true,");
		}
		if (test->kind == HFTEST_KIND_TEST) {
			if (!tests_in_suite) {
				HFTEST_LOG("      \"tests\": [");
			}
			/*
			 * It's easier to put the comma at the start of the line
			 * than the end even though the JSON looks a bit funky.
			 */
			HFTEST_LOG("       %c{", tests_in_suite ? ',' : ' ');
			HFTEST_LOG("          \"name\": \"%s\",", test->name);
			HFTEST_LOG("          \"is_long_running\": %s",
				   test->is_long_running ? "true" : "false");
			HFTEST_LOG("       }");
			++tests_in_suite;
		}
	}
	if (tests_in_suite) {
		HFTEST_LOG("      ]");
		HFTEST_LOG("    }");
	}
	HFTEST_LOG("  ]");
	HFTEST_LOG("}");
}

/**
 * Logs a failure message and shut down.
 */
noreturn void abort(void)
{
	HFTEST_LOG("FAIL");
	arch_power_off();
}

static void run_test(hftest_test_fn set_up, hftest_test_fn test,
		     hftest_test_fn tear_down, const struct fdt_header *fdt)
{
	/* Prepare the context. */
	struct hftest_context *ctx = hftest_get_context();
	memset_s(ctx, sizeof(*ctx), 0, sizeof(*ctx));
	ctx->abort = abort;
	ctx->fdt = fdt;

	/* Run any set up functions. */
	if (set_up) {
		set_up();
		if (ctx->failures) {
			abort();
		}
	}

	/* Run the test. */
	test();
	if (ctx->failures) {
		abort();
	}

	/* Run any tear down functions. */
	if (tear_down) {
		tear_down();
		if (ctx->failures) {
			abort();
		}
	}

	HFTEST_LOG("FINISHED");
}

/**
 * Runs the given test case.
 */
void hftest_run(struct memiter suite_name, struct memiter test_name,
		const struct fdt_header *fdt)
{
	size_t i;
	hftest_test_fn suite_set_up = NULL;
	hftest_test_fn suite_tear_down = NULL;

	for (i = 0; i < hftest_count; ++i) {
		struct hftest_test *test = &hftest_list[i];

		/* Check if this test is part of the suite we want. */
		if (memiter_iseq(&suite_name, test->suite)) {
			switch (test->kind) {
			/*
			 * The first entries in the suite are the set up and
			 * tear down functions.
			 */
			case HFTEST_KIND_SET_UP:
				suite_set_up = test->fn;
				break;
			case HFTEST_KIND_TEAR_DOWN:
				suite_tear_down = test->fn;
				break;
			/* Find the test. */
			case HFTEST_KIND_TEST:
				if (memiter_iseq(&test_name, test->name)) {
					run_test(suite_set_up, test->fn,
						 suite_tear_down, fdt);
					return;
				}
				break;
			default:
				/* Ignore other kinds. */
				break;
			}
		}
	}

	HFTEST_LOG("Unable to find requested tests.");
}

/**
 * Writes out usage information.
 */
void hftest_help(void)
{
	HFTEST_LOG("usage:");
	HFTEST_LOG("");
	HFTEST_LOG("  help");
	HFTEST_LOG("");
	HFTEST_LOG("    Show this help.");
	HFTEST_LOG("");
	HFTEST_LOG("  json");
	HFTEST_LOG("");
	HFTEST_LOG(
		"    Print a directory of test suites and tests in "
		"JSON "
		"format.");
	HFTEST_LOG("");
	HFTEST_LOG("  run <suite> <test>");
	HFTEST_LOG("");
	HFTEST_LOG("    Run the named test from the named test suite.");
}

static uintptr_t vcpu_index_to_id(size_t index)
{
	/* For now we use indices as IDs for vCPUs. */
	return index;
}

/**
 * Get the ID of the CPU with the given index.
 */
uintptr_t hftest_get_cpu_id(size_t index)
{
	struct boot_params params;
	struct fdt_node n;
	const struct fdt_header *fdt = hftest_get_context()->fdt;

	if (fdt == NULL) {
		/*
		 * We must be in a service VM, so apply the mapping that Hafnium
		 * uses for vCPU IDs.
		 */
		return vcpu_index_to_id(index);
	}

	/* Find physical CPU ID from FDT. */
	if (!fdt_root_node(&n, fdt)) {
		FAIL("FDT failed validation.");
	}
	if (!fdt_find_child(&n, "")) {
		FAIL("Unable to find FDT root node.");
	}
	fdt_find_cpus(&n, params.cpu_ids, &params.cpu_count);

	return params.cpu_ids[index];
}
