/* Copyright 2020 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 host flashrom utilities.
 */

/* For strdup */
#define _POSIX_C_SOURCE 200809L

#include <fcntl.h>
#include <getopt.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "2common.h"
#include "2return_codes.h"
#include "host_misc.h"
#include "flashrom.h"
#include "subprocess.h"
#include "test_common.h"

#define MOCK_TMPFILE_NAME "/tmp/vb2_unittest"
#define MOCK_ROM_CONTENTS "bloop123"

static bool flashrom_mock_success = true;
static enum { FLASHROM_NONE, FLASHROM_READ, FLASHROM_WRITE } captured_operation;
static enum {
	FLASHROM_VERIFY_UNSPECIFIED,
	FLASHROM_VERIFY_FAST,
} captured_verify;
static const char *captured_op_filename;
static const char *captured_region_param;
static const char *captured_programmer;
static uint8_t *captured_rom_contents;
static uint32_t captured_rom_size;

/* Mocked mkstemp for tests. */
int mkstemp(char *template_name)
{
	strncpy(template_name, MOCK_TMPFILE_NAME, strlen(template_name));
	return open(template_name, O_RDWR | O_CREAT | O_TRUNC, 0666);
}

/* Mocked subprocess_run for tests. */
int subprocess_run(const char *const argv[],
		   struct subprocess_target *input,
		   struct subprocess_target *output,
		   struct subprocess_target *error)
{
	int argc;
	int opt;
	int rv;
	/* getopt_long wants an int instead of an enum, bummer... */
	int captured_verify_int = FLASHROM_VERIFY_UNSPECIFIED;
	struct option long_opts[] = {
		{
			.name = "fast-verify",
			.has_arg = no_argument,
			.flag = &captured_verify_int,
			.val = FLASHROM_VERIFY_FAST,
		},
	};

	/* Reset static variables to their defaults. */
	captured_operation = FLASHROM_NONE;
	captured_operation = FLASHROM_VERIFY_UNSPECIFIED;
	captured_op_filename = NULL;
	captured_region_param = NULL;
	captured_programmer = NULL;
	captured_rom_contents = NULL;
	captured_rom_size = 0;
	optind = 0;

	/* Count the number of arguments, a required formalism for
	   getopt. */
	for (argc = 0; argv[argc]; argc++)
		continue;

	/* We only understand the subset of arguments used by the
	   wrapper library.  If it's updated to support more modes of
	   operation, this unit test code should be updated too. */
	while ((opt = getopt_long(argc, (char *const *)argv,
				  ":p:r:w:i:", long_opts, NULL)) != -1) {
		/* Always consume the next argument if it does not
		   start with a dash.  We have to muck with getopt's
		   global variables to make this happen. */
		if (opt == ':' && argv[optind] && argv[optind][0] != '-') {
			optarg = strdup(argv[optind]);
			optind++;
			opt = optopt;
		} else if (optarg && optarg[0] == '-') {
			optarg = NULL;
			optind--;
		} else if (optarg) {
			optarg = strdup(optarg);
		}

		switch (opt) {
		case 'p':
			captured_programmer = optarg;
			break;
		case 'r':
			captured_operation = FLASHROM_READ;
			captured_op_filename = optarg;
			break;
		case 'w':
			captured_operation = FLASHROM_WRITE;
			captured_op_filename = optarg;
			break;
		case 'i':
			captured_region_param = optarg;
			break;
		case 0:
			/* long option */
			break;
		default:
			return 1;
		}
	}

	if (optind != argc) {
		/* Extra arguments we don't understand. */
		return 1;
	}

	rv = !flashrom_mock_success;
	captured_verify = captured_verify_int;

	if (captured_operation == FLASHROM_READ) {
		/* Write the mocked string we read from the ROM. */
		rv |= vb2_write_file(MOCK_TMPFILE_NAME, MOCK_ROM_CONTENTS,
				     strlen(MOCK_ROM_CONTENTS));
	} else if (captured_operation == FLASHROM_WRITE) {
		/* Capture the buffer contents we wrote to the ROM. */
		rv |= vb2_read_file(MOCK_TMPFILE_NAME, &captured_rom_contents,
				    &captured_rom_size);
	}

	return rv;
}

static void test_read_whole_chip(void)
{
	uint8_t *buf;
	uint32_t buf_sz;

	TEST_SUCC(flashrom_read("someprog", NULL, &buf, &buf_sz),
		  "Flashrom read succeeds");
	TEST_STR_EQ(captured_programmer, "someprog",
		    "Using specified programmer");
	TEST_EQ(captured_operation, FLASHROM_READ, "Doing a read operation");
	TEST_EQ(captured_verify, FLASHROM_VERIFY_UNSPECIFIED,
		"Verification not enabled");
	TEST_STR_EQ(captured_op_filename, MOCK_TMPFILE_NAME,
		    "Reading to correct file");
	TEST_PTR_EQ(captured_region_param, NULL, "Not operating on a region");
	TEST_EQ(buf_sz, strlen(MOCK_ROM_CONTENTS), "Contents correct size");
	TEST_SUCC(memcmp(buf, MOCK_ROM_CONTENTS, buf_sz),
		  "Buffer has correct contents");

	free(buf);
}

static void test_read_region(void)
{
	uint8_t *buf;
	uint32_t buf_sz;

	TEST_SUCC(flashrom_read("someprog", "SOME_REGION", &buf, &buf_sz),
		  "Flashrom read succeeds");
	TEST_STR_EQ(captured_programmer, "someprog",
		    "Using specified programmer");
	TEST_EQ(captured_operation, FLASHROM_READ, "Doing a read operation");
	TEST_EQ(captured_verify, FLASHROM_VERIFY_UNSPECIFIED,
		"Verification not enabled");
	TEST_PTR_EQ(captured_op_filename, NULL,
		    "Not doing a read of the whole ROM");
	TEST_STR_EQ(captured_region_param, "SOME_REGION:" MOCK_TMPFILE_NAME,
		    "Reading to correct file and from correct region");
	TEST_EQ(buf_sz, strlen(MOCK_ROM_CONTENTS), "Contents correct size");
	TEST_SUCC(memcmp(buf, MOCK_ROM_CONTENTS, buf_sz),
		  "Buffer has correct contents");

	free(buf);
}

static void test_read_failure(void)
{
	uint8_t *buf;
	uint32_t buf_sz;

	flashrom_mock_success = false;
	TEST_NEQ(flashrom_read("someprog", "SOME_REGION", &buf, &buf_sz),
		 VB2_SUCCESS, "Flashrom read fails");
	flashrom_mock_success = true;
}

static void test_write_whole_chip(void)
{
	uint8_t buf[sizeof(MOCK_ROM_CONTENTS) - 1];

	memcpy(buf, MOCK_ROM_CONTENTS, sizeof(buf));

	TEST_SUCC(flashrom_write("someprog", NULL, buf, sizeof(buf)),
		  "Flashrom write succeeds");
	TEST_STR_EQ(captured_programmer, "someprog",
		    "Using specified programmer");
	TEST_EQ(captured_operation, FLASHROM_WRITE, "Doing a write operation");
	TEST_EQ(captured_verify, FLASHROM_VERIFY_FAST,
		"Fast verification enabled");
	TEST_STR_EQ(captured_op_filename, MOCK_TMPFILE_NAME,
		    "Writing to correct file");
	TEST_PTR_EQ(captured_region_param, NULL, "Not operating on a region");
	TEST_EQ(captured_rom_size, strlen(MOCK_ROM_CONTENTS),
		"Contents correct size");
	TEST_SUCC(memcmp(captured_rom_contents, MOCK_ROM_CONTENTS,
			 captured_rom_size), "Buffer has correct contents");
}

static void test_write_region(void)
{
	uint8_t buf[sizeof(MOCK_ROM_CONTENTS) - 1];

	memcpy(buf, MOCK_ROM_CONTENTS, sizeof(buf));

	TEST_SUCC(flashrom_write("someprog", "SOME_REGION", buf, sizeof(buf)),
		  "Flashrom write succeeds");
	TEST_STR_EQ(captured_programmer, "someprog",
		    "Using specified programmer");
	TEST_EQ(captured_operation, FLASHROM_WRITE, "Doing a write operation");
	TEST_EQ(captured_verify, FLASHROM_VERIFY_FAST,
		"Fast verification enabled");
	TEST_PTR_EQ(captured_op_filename, NULL,
		    "Not doing a write of the whole ROM");
	TEST_STR_EQ(captured_region_param, "SOME_REGION:" MOCK_TMPFILE_NAME,
		    "Writing to correct file and from correct region");
	TEST_EQ(captured_rom_size, strlen(MOCK_ROM_CONTENTS),
		"Contents correct size");
	TEST_SUCC(memcmp(captured_rom_contents, MOCK_ROM_CONTENTS,
			 captured_rom_size), "Buffer has correct contents");
}

static void test_write_failure(void)
{
	uint8_t buf[20] = { 0 };

	flashrom_mock_success = false;
	TEST_NEQ(flashrom_write("someprog", "SOME_REGION", buf, sizeof(buf)),
		 VB2_SUCCESS, "Flashrom write fails");
	flashrom_mock_success = true;
}

int main(int argc, char *argv[])
{
	test_read_whole_chip();
	test_read_region();
	test_read_failure();
	test_write_whole_chip();
	test_write_region();
	test_write_failure();

	return gTestSuccess ? 0 : 255;
}
