/*
 * Copyright 2012, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 *      copyright notice, this list of conditions and the following disclaimer
 *      in the documentation and/or other materials provided with the
 *      distribution.
 *    * Neither the name of Google Inc. nor the names of its
 *      contributors may be used to endorse or promote products derived from
 *      this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * flashrom.c: flashrom wrappers
 */

#include <ctype.h>
#include <fcntl.h>
#include <inttypes.h>
#include <limits.h>
#include <stdlib.h>
#include <unistd.h>

#include <sys/types.h>
#include <sys/stat.h>

#include "mosys/alloc.h"
#include "mosys/big_lock.h"
#include "mosys/log.h"

#include "lib/flashrom.h"
#include "lib/string_builder.h"

/* returns pointer to string containing flashrom path if successful,
   returns NULL otherwise */
static const char *flashrom_path(void)
{
	FILE *fp;
	static char path[PATH_MAX];
	int c, i = 0;

	if ((fp = popen("which flashrom 2>/dev/null", "r")) == NULL) {
		lprintf(LOG_DEBUG, "Cannot find flashrom\n");
		return NULL;
	}

	for (i = 0; i < PATH_MAX; i++) {
		c = fgetc(fp);

		if (c == EOF || c == '\n') {
			path[i] = '\0';
			break;
		}
		path[i] = c;
	}

	pclose(fp);
	/* no characters were read from stream, or buffer overrun */
	if ((c == EOF && i == 0) || (c != EOF && i == PATH_MAX))
		return NULL;
	return path;
}

static int do_flashrom(const char *cmd)
{
	int rc = 0;
#if defined(CONFIG_USE_IPC_LOCK)
	int re_acquire_lock = 1;
#endif

#if defined(CONFIG_USE_IPC_LOCK)
	if (mosys_release_big_lock() < 0)
		re_acquire_lock = 0;
#endif

	if (system(cmd) != 0) {
		lprintf(LOG_DEBUG, "%s: Failed to run %s\n", __func__, cmd);
		rc = -1;
	}

#if defined(CONFIG_USE_IPC_LOCK)
        /* try to get lock */
        if (re_acquire_lock && (mosys_acquire_big_lock(50000) < 0)) {
		lprintf(LOG_DEBUG, "%s: could not re-acquire lock\n", __func__);
		rc = -1;
        }
#endif

	return rc;
}

/* TODO: add arbitrary range support */
int flashrom_read(uint8_t *buf, size_t size,
                  enum target_bus target, const char *region)
{
	int fd, rc = -1;
	struct string_builder *sb = new_string_builder();
	char *flashrom_cmd;
	char filename[] = "/tmp/flashrom_XXXXXX";
	struct stat s;
	const char *path;

	if ((path = flashrom_path()) == NULL)
		goto flashrom_read_exit_1;

	string_builder_sprintf(sb, path);

	switch(target) {
	case INTERNAL_BUS_SPI:
		string_builder_strcat(sb, " -p internal:bus=spi");
		break;
	case INTERNAL_BUS_I2C:
		string_builder_strcat(sb, " -p internal:bus=i2c");
		break;
	case INTERNAL_BUS_LPC:
		string_builder_strcat(sb, " -p internal:bus=lpc");
		break;
	default:
		lprintf(LOG_DEBUG, "Unsupported target: %d\n", target);
		goto flashrom_read_exit_1;
	}

	if (!mkstemp(filename)) {
		lperror(LOG_DEBUG, "Unable to make temporary file for flashrom");
		goto flashrom_read_exit_1;
	}

	if (region) {
		string_builder_strcat(sb, " -i ");
		string_builder_strcat(sb, region);
	}

	string_builder_strcat(sb, " -r ");
	string_builder_strcat(sb, filename);
	string_builder_strcat(sb, " >/dev/null 2>&1");

	flashrom_cmd = mosys_strdup(string_builder_get_string(sb));
	lprintf(LOG_DEBUG, "Calling \"%s\"\n", flashrom_cmd);
	if (do_flashrom(flashrom_cmd) < 0)
		goto flashrom_read_exit_2;

	fd = open(filename, O_RDONLY);
	if (fstat(fd, &s) < 0) {
		lprintf(LOG_DEBUG, "%s: Cannot stat %s\n", __func__, filename);
		goto flashrom_read_exit_2;
	}

	if (s.st_size != size) {
		lprintf(LOG_DEBUG, "%s: Size of image: %lu, expected %lu",
		                   __func__, s.st_size, size);
		goto flashrom_read_exit_2;
	}

	if (read(fd, buf, size) != size) {
		lperror(LOG_DEBUG, "%s: Unable to read image");
		goto flashrom_read_exit_2;
	}

	rc = 0;
flashrom_read_exit_2:
	free(flashrom_cmd);
flashrom_read_exit_1:
	unlink(filename);
	free_string_builder(sb);
	return rc;
}

int flashrom_read_by_name(uint8_t **buf,
                  enum target_bus target, const char *region)
{
	int fd, rc = -1;
	struct string_builder *sb = new_string_builder();
	char *flashrom_cmd;
	char filename[] = "/tmp/flashrom_XXXXXX";
	struct stat s;
	const char *path;

	if (!region)
		goto flashrom_read_exit_0;

	if ((path = flashrom_path()) == NULL)
		goto flashrom_read_exit_0;

	string_builder_sprintf(sb, path);

	switch(target) {
	case INTERNAL_BUS_SPI:
		string_builder_strcat(sb, " -p internal:bus=spi");
		break;
	case INTERNAL_BUS_I2C:
		string_builder_strcat(sb, " -p internal:bus=i2c");
		break;
	case INTERNAL_BUS_LPC:
		string_builder_strcat(sb, " -p internal:bus=lpc");
		break;
	default:
		lprintf(LOG_DEBUG, "Unsupported target: %d\n", target);
		goto flashrom_read_exit_1;
	}

	if (!mkstemp(filename)) {
		lperror(LOG_DEBUG, "Unable to make temporary file for flashrom");
		goto flashrom_read_exit_1;
	}

	string_builder_strcat(sb, " -i ");
	string_builder_strcat(sb, region);
	string_builder_strcat(sb, ":");
	string_builder_strcat(sb, filename);

	string_builder_strcat(sb, " -r /dev/null");
	string_builder_strcat(sb, " >/dev/null 2>&1");

	flashrom_cmd = mosys_strdup(string_builder_get_string(sb));
	lprintf(LOG_DEBUG, "Calling \"%s\"\n", flashrom_cmd);
	if (do_flashrom(flashrom_cmd) < 0) {
		lprintf(LOG_DEBUG, "Unable to read region \"%s\"\n", region);
		goto flashrom_read_exit_2;
	}

	fd = open(filename, O_RDONLY);
	if (fstat(fd, &s) < 0) {
		lprintf(LOG_DEBUG, "%s: Cannot stat %s\n", __func__, filename);
		goto flashrom_read_exit_2;
	}

	*buf = mosys_malloc(s.st_size);
	if (read(fd, *buf, s.st_size) < 0) {
		lperror(LOG_DEBUG, "%s: Unable to read image");
		free(*buf);
		goto flashrom_read_exit_2;
	}

	rc = s.st_size;
flashrom_read_exit_2:
	free(flashrom_cmd);
flashrom_read_exit_1:
	unlink(filename);
flashrom_read_exit_0:
	free_string_builder(sb);
	return rc;
}
