/* Copyright 2013-2017 IBM Corp.
 *
 * 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
 *
 * 	http://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 <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <stdbool.h>
#include <errno.h>
#include <string.h>
#include <inttypes.h>

#include <libflash/libflash.h>
#include <libflash/errors.h>

#include "blocklevel.h"
#include "ecc.h"

#define PROT_REALLOC_NUM 25

/* This function returns tristate values.
 * 1  - The region is ECC protected
 * 0  - The region is not ECC protected
 * -1 - Partially protected
 */
static int ecc_protected(struct blocklevel_device *bl, uint64_t pos, uint64_t len, uint64_t *start)
{
	int i;

	/* Length of 0 is nonsensical so add 1 */
	if (len == 0)
		len = 1;

	for (i = 0; i < bl->ecc_prot.n_prot; i++) {
		/* Fits entirely within the range */
		if (bl->ecc_prot.prot[i].start <= pos &&
				bl->ecc_prot.prot[i].start + bl->ecc_prot.prot[i].len >= pos + len) {
			if (start)
				*start = bl->ecc_prot.prot[i].start;
			return 1;
		}

		/*
		 * Even if ranges are merged we can't currently guarantee two
		 * contiguous regions are sanely ECC protected so a partial fit
		 * is no good.
		 */
		if ((bl->ecc_prot.prot[i].start >= pos && bl->ecc_prot.prot[i].start < pos + len) ||
		   (bl->ecc_prot.prot[i].start <= pos &&
			bl->ecc_prot.prot[i].start + bl->ecc_prot.prot[i].len > pos)) {
			if (start)
				*start = bl->ecc_prot.prot[i].start;
			return -1;
		}
	}
	return 0;
}

static uint64_t with_ecc_pos(uint64_t ecc_start, uint64_t pos)
{
	return pos + ((pos - ecc_start) / (BYTES_PER_ECC));
}

static int reacquire(struct blocklevel_device *bl)
{
	if (!bl->keep_alive && bl->reacquire)
		return bl->reacquire(bl);
	return 0;
}

static int release(struct blocklevel_device *bl)
{
	int rc = 0;
	if (!bl->keep_alive && bl->release) {
		/* This is the error return path a lot, preserve errno */
		int err = errno;
		rc = bl->release(bl);
		errno = err;
	}
	return rc;
}

int blocklevel_raw_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len)
{
	int rc;

	FL_DBG("%s: 0x%" PRIx64 "\t%p\t0x%" PRIx64 "\n", __func__, pos, buf, len);
	if (!bl || !bl->read || !buf) {
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	rc = reacquire(bl);
	if (rc)
		return rc;

	rc = bl->read(bl, pos, buf, len);

	release(bl);

	return rc;
}

int blocklevel_read(struct blocklevel_device *bl, uint64_t pos, void *buf, uint64_t len)
{
	int rc, ecc_protection;
	struct ecc64 *buffer;
	uint64_t ecc_pos, ecc_start, ecc_diff, ecc_len;

	FL_DBG("%s: 0x%" PRIx64 "\t%p\t0x%" PRIx64 "\n", __func__, pos, buf, len);
	if (!bl || !buf) {
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	ecc_protection = ecc_protected(bl, pos, len, &ecc_start);

	FL_DBG("%s: 0x%" PRIx64 " for 0x%" PRIx64 " ecc=%s\n",
		__func__, pos, len, ecc_protection ?
		(ecc_protection == -1 ? "partial" : "yes") : "no");

	if (!ecc_protection)
		return blocklevel_raw_read(bl, pos, buf, len);

	/*
	 * The region we're reading to has both ecc protection and not.
	 * Perhaps one day in the future blocklevel can cope with this.
	 */
	if (ecc_protection == -1) {
		FL_ERR("%s: Can't cope with partial ecc\n", __func__);
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	pos = with_ecc_pos(ecc_start, pos);

	ecc_pos = ecc_buffer_align(ecc_start, pos);
	ecc_diff = pos - ecc_pos;
	ecc_len = ecc_buffer_size(len + ecc_diff);

	FL_DBG("%s: adjusted_pos: 0x%" PRIx64 ", ecc_pos: 0x%" PRIx64
			", ecc_diff: 0x%" PRIx64 ", ecc_len: 0x%" PRIx64 "\n",
			__func__, pos, ecc_pos, ecc_diff, ecc_len);
	buffer = malloc(ecc_len);
	if (!buffer) {
		errno = ENOMEM;
		rc = FLASH_ERR_MALLOC_FAILED;
		goto out;
	}

	rc = blocklevel_raw_read(bl, ecc_pos, buffer, ecc_len);
	if (rc)
		goto out;

	/*
	 * Could optimise and simply call memcpy_from_ecc() if ecc_diff
	 * == 0 but _unaligned checks and bascially does that for us
	 */
	if (memcpy_from_ecc_unaligned(buf, buffer, len, ecc_diff)) {
		errno = EBADF;
		rc = FLASH_ERR_ECC_INVALID;
	}

out:
	free(buffer);
	return rc;
}

int blocklevel_raw_write(struct blocklevel_device *bl, uint64_t pos,
		const void *buf, uint64_t len)
{
	int rc;

	FL_DBG("%s: 0x%" PRIx64 "\t%p\t0x%" PRIx64 "\n", __func__, pos, buf, len);
	if (!bl || !bl->write || !buf) {
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	rc = reacquire(bl);
	if (rc)
		return rc;

	rc = bl->write(bl, pos, buf, len);

	release(bl);

	return rc;
}

int blocklevel_write(struct blocklevel_device *bl, uint64_t pos, const void *buf,
		uint64_t len)
{
	int rc, ecc_protection;
	struct ecc64 *buffer;
	uint64_t ecc_len = ecc_buffer_size(len);
	uint64_t ecc_start, ecc_pos, ecc_diff;

	FL_DBG("%s: 0x%" PRIx64 "\t%p\t0x%" PRIx64 "\n", __func__, pos, buf, len);
	if (!bl || !buf) {
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	ecc_protection = ecc_protected(bl, pos, len, &ecc_start);

	FL_DBG("%s: 0x%" PRIx64 " for 0x%" PRIx64 " ecc=%s\n",
		__func__, pos, len, ecc_protection ?
		(ecc_protection == -1 ? "partial" : "yes") : "no");

	if (!ecc_protection)
		return blocklevel_raw_write(bl, pos, buf, len);

	/*
	 * The region we're writing to has both ecc protection and not.
	 * Perhaps one day in the future blocklevel can cope with this.
	 */
	if (ecc_protection == -1) {
		FL_ERR("%s: Can't cope with partial ecc\n", __func__);
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	pos = with_ecc_pos(ecc_start, pos);

	ecc_pos = ecc_buffer_align(ecc_start, pos);
	ecc_diff = pos - ecc_pos;
	ecc_len = ecc_buffer_size(len + ecc_diff);

	FL_DBG("%s: adjusted_pos: 0x%" PRIx64 ", ecc_pos: 0x%" PRIx64
			", ecc_diff: 0x%" PRIx64 ", ecc_len: 0x%" PRIx64 "\n",
			__func__, pos, ecc_pos, ecc_diff, ecc_len);

	buffer = malloc(ecc_len);
	if (!buffer) {
		errno = ENOMEM;
		rc = FLASH_ERR_MALLOC_FAILED;
		goto out;
	}

	if (ecc_diff) {
		uint64_t start_chunk = ecc_diff;
		uint64_t end_chunk = BYTES_PER_ECC - ecc_diff;
		uint64_t end_len = ecc_len - end_chunk;

		/*
		 * Read the start bytes that memcpy_to_ecc_unaligned() will need
		 * to calculate the first ecc byte
		 */
		rc = blocklevel_raw_read(bl, ecc_pos, buffer, start_chunk);
		if (rc) {
			errno = EBADF;
			rc = FLASH_ERR_ECC_INVALID;
		}

		/*
		 * Read the end bytes that memcpy_to_ecc_unaligned() will need
		 * to calculate the last ecc byte
		 */
		rc = blocklevel_raw_read(bl, ecc_pos + end_len, ((char *)buffer) + end_len,
				end_chunk);
		if (rc) {
			errno = EBADF;
			rc = FLASH_ERR_ECC_INVALID;
		}

		if (memcpy_to_ecc_unaligned(buffer, buf, len, ecc_diff)) {
			errno = EBADF;
			rc = FLASH_ERR_ECC_INVALID;
			goto out;
		}
	} else {
		if (memcpy_to_ecc(buffer, buf, len)) {
			errno = EBADF;
			rc = FLASH_ERR_ECC_INVALID;
			goto out;
		}
	}
	rc = blocklevel_raw_write(bl, pos, buffer, ecc_len);

out:
	free(buffer);
	return rc;
}

int blocklevel_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t len)
{
	int rc;
	if (!bl || !bl->erase) {
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	FL_DBG("%s: 0x%" PRIx64 "\t0x%" PRIx64 "\n", __func__, pos, len);

	/* Programmer may be making a horrible mistake without knowing it */
	if (pos & bl->erase_mask) {
		FL_ERR("blocklevel_erase: pos (0x%"PRIx64") is not erase block (0x%08x) aligned\n",
				pos, bl->erase_mask + 1);
		return FLASH_ERR_ERASE_BOUNDARY;
	}

	if (len & bl->erase_mask) {
		FL_ERR("blocklevel_erase: len (0x%"PRIx64") is not erase block (0x%08x) aligned\n",
				len, bl->erase_mask + 1);
		return FLASH_ERR_ERASE_BOUNDARY;
	}

	rc = reacquire(bl);
	if (rc)
		return rc;

	rc = bl->erase(bl, pos, len);

	release(bl);

	return rc;
}

int blocklevel_get_info(struct blocklevel_device *bl, const char **name, uint64_t *total_size,
		uint32_t *erase_granule)
{
	int rc;

	if (!bl || !bl->get_info) {
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	rc = reacquire(bl);
	if (rc)
		return rc;

	rc = bl->get_info(bl, name, total_size, erase_granule);

	/* Check the validity of what we are being told */
	if (erase_granule && *erase_granule != bl->erase_mask + 1)
		FL_ERR("blocklevel_get_info: WARNING: erase_granule (0x%08x) and erase_mask"
				" (0x%08x) don't match\n", *erase_granule, bl->erase_mask + 1);

	release(bl);

	return rc;
}

/*
 * Compare flash and memory to determine if:
 * a) Erase must happen before write
 * b) Flash and memory are identical
 * c) Flash can simply be written to
 *
 * returns -1 for a
 * returns  0 for b
 * returns  1 for c
 */
static int blocklevel_flashcmp(const void *flash_buf, const void *mem_buf, uint64_t len)
{
	uint64_t i;
	int same = true;
	const uint8_t *f_buf, *m_buf;

	f_buf = flash_buf;
	m_buf = mem_buf;

	for (i = 0; i < len; i++) {
		if (m_buf[i] & ~f_buf[i])
			return -1;
		if (same && (m_buf[i] != f_buf[i]))
			same = false;
	}

	return same ? 0 : 1;
}

int blocklevel_smart_erase(struct blocklevel_device *bl, uint64_t pos, uint64_t len)
{
	uint64_t block_size;
	void *erase_buf;
	int rc;

	if (!bl) {
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	FL_DBG("%s: 0x%" PRIx64 "\t0x%" PRIx64 "\n", __func__, pos, len);

	/* Nothing smart needs to be done, pos and len are aligned */
	if ((pos & bl->erase_mask) == 0 && (len & bl->erase_mask) == 0) {
		FL_DBG("%s: Skipping smarts everything is aligned 0x%" PRIx64 " 0x%" PRIx64
				"to 0x%08x\n", __func__, pos, len, bl->erase_mask);
		return blocklevel_erase(bl, pos, len);
	}
	block_size = bl->erase_mask + 1;
	erase_buf = malloc(block_size);
	if (!erase_buf) {
		errno = ENOMEM;
		return FLASH_ERR_MALLOC_FAILED;
	}

	rc = reacquire(bl);
	if (rc) {
		free(erase_buf);
		return rc;
	}

	if (pos & bl->erase_mask) {
		/*
		 * base_pos and base_len are the values in the first erase
		 * block that we need to preserve: the region up to pos.
		 */
		uint64_t base_pos = pos & ~(bl->erase_mask);
		uint64_t base_len = pos - base_pos;

		FL_DBG("%s: preserving 0x%" PRIx64 "..0x%" PRIx64 "\n",
				__func__, base_pos, base_pos + base_len);

		/*
		 * Read the entire block in case this is the ONLY block we're
		 * modifying, we may need the end chunk of it later
		 */
		rc = bl->read(bl, base_pos, erase_buf, block_size);
		if (rc)
			goto out;

		rc = bl->erase(bl, base_pos, block_size);
		if (rc)
			goto out;

		rc = bl->write(bl, base_pos, erase_buf, base_len);
		if (rc)
			goto out;

		/*
		 * The requested erase fits entirely into this erase block and
		 * so we need to write back the chunk at the end of the block
		 */
		if (base_pos + base_len + len < base_pos + block_size) {
			rc = bl->write(bl, pos + len, erase_buf + base_len + len,
					block_size - base_len - len);
			FL_DBG("%s: Early exit, everything was in one erase block\n",
					__func__);
			goto out;
		}

		pos += block_size - base_len;
		len -= block_size - base_len;
	}

	/* Now we should be aligned, best to double check */
	if (pos & bl->erase_mask) {
		FL_DBG("%s:pos 0x%" PRIx64 " isn't erase_mask 0x%08x aligned\n",
			   	__func__, pos, bl->erase_mask);
		rc = FLASH_ERR_PARM_ERROR;
		goto out;
	}

	if (len & ~(bl->erase_mask)) {
		rc = bl->erase(bl, pos, len & ~(bl->erase_mask));
		if (rc)
			goto out;

		pos += len & ~(bl->erase_mask);
		len -= len & ~(bl->erase_mask);
	}

	/* Length should be less than a block now */
	if (len > block_size) {
		FL_DBG("%s: len 0x%" PRIx64 " is still exceeds block_size 0x%" PRIx64 "\n",
				__func__, len, block_size);
		rc = FLASH_ERR_PARM_ERROR;
		goto out;
	}

	if (len & bl->erase_mask) {
		/*
		 * top_pos is the first byte that must be preserved and
		 * top_len is the length from top_pos to the end of the erase
		 * block: the region that must be preserved
		 */
		uint64_t top_pos = pos + len;
		uint64_t top_len = block_size - len;

		FL_DBG("%s: preserving 0x%" PRIx64 "..0x%" PRIx64 "\n",
				__func__, top_pos, top_pos + top_len);

		rc = bl->read(bl, top_pos, erase_buf, top_len);
		if (rc)
			goto out;

		rc = bl->erase(bl, pos, block_size);
		if (rc)
			goto out;

		rc = bl->write(bl, top_pos, erase_buf, top_len);
		if (rc)
			goto out;
	}

out:
	free(erase_buf);
	release(bl);
	return rc;
}

int blocklevel_smart_write(struct blocklevel_device *bl, uint64_t pos, const void *buf, uint64_t len)
{
	uint32_t erase_size;
	const void *write_buf = buf;
	void *write_buf_start = NULL;
	uint64_t ecc_start;
	void *erase_buf;
	int rc = 0;

	if (!write_buf || !bl) {
		errno = EINVAL;
		return FLASH_ERR_PARM_ERROR;
	}

	FL_DBG("%s: 0x%" PRIx64 "\t0x%" PRIx64 "\n", __func__, pos, len);

	if (!(bl->flags & WRITE_NEED_ERASE)) {
		FL_DBG("%s: backend doesn't need erase\n", __func__);
		return blocklevel_write(bl, pos, buf, len);
	}

	rc = blocklevel_get_info(bl, NULL, NULL, &erase_size);
	if (rc)
		return rc;

	if (ecc_protected(bl, pos, len, &ecc_start)) {
		FL_DBG("%s: region has ECC\n", __func__);

		len = ecc_buffer_size(len);

		write_buf_start = malloc(len);
		if (!write_buf_start) {
			errno = ENOMEM;
			return FLASH_ERR_MALLOC_FAILED;
		}

		if (memcpy_to_ecc(write_buf_start, buf, ecc_buffer_size_minus_ecc(len))) {
			free(write_buf_start);
			errno = EBADF;
			return FLASH_ERR_ECC_INVALID;
		}
		write_buf = write_buf_start;
	}

	erase_buf = malloc(erase_size);
	if (!erase_buf) {
		errno = ENOMEM;
		rc = FLASH_ERR_MALLOC_FAILED;
		goto out_free;
	}

	rc = reacquire(bl);
	if (rc)
		goto out_free;

	while (len > 0) {
		uint32_t erase_block = pos & ~(erase_size - 1);
		uint32_t block_offset = pos & (erase_size - 1);
		uint32_t size = erase_size > len ? len : erase_size;
		int cmp;

		/* Write crosses an erase boundary, shrink the write to the boundary */
		if (erase_size < block_offset + size) {
			size = erase_size - block_offset;
		}

		rc = bl->read(bl, erase_block, erase_buf, erase_size);
		if (rc)
			goto out;

		cmp = blocklevel_flashcmp(erase_buf + block_offset, write_buf, size);
		FL_DBG("%s: region 0x%08x..0x%08x ", __func__,
				erase_block, erase_size);
		if (cmp != 0) {
			FL_DBG("needs ");
			if (cmp == -1) {
				FL_DBG("erase and ");
				bl->erase(bl, erase_block, erase_size);
			}
			FL_DBG("write\n");
			memcpy(erase_buf + block_offset, write_buf, size);
			rc = bl->write(bl, erase_block, erase_buf, erase_size);
			if (rc)
				goto out;
		}
		len -= size;
		pos += size;
		write_buf += size;
	}

out:
	release(bl);
out_free:
	free(write_buf_start);
	free(erase_buf);
	return rc;
}

static bool insert_bl_prot_range(struct blocklevel_range *ranges, struct bl_prot_range range)
{
	int i;
	uint32_t pos, len;
	struct bl_prot_range *prot = ranges->prot;

	pos = range.start;
	len = range.len;

	if (len == 0)
		return true;

	/* Check for overflow */
	if (pos + len < len)
		return false;

	for (i = 0; i < ranges->n_prot && len > 0; i++) {
		if (prot[i].start <= pos && prot[i].start + prot[i].len >= pos + len) {
			len = 0;
			break; /* Might as well, the next two conditions can't be true */
		}

		/* Can easily extend this down just by adjusting start */
		if (pos <= prot[i].start && pos + len >= prot[i].start) {
			FL_DBG("%s: extending start down\n", __func__);
			prot[i].len += prot[i].start - pos;
			prot[i].start = pos;
			pos += prot[i].len;
			if (prot[i].len >= len)
				len = 0;
			else
				len -= prot[i].len;
		}

		/*
		 * Jump over this range but the new range might be so big that
		 * theres a chunk after
		 */
		if (pos >= prot[i].start && pos < prot[i].start + prot[i].len) {
			FL_DBG("%s: fits within current range ", __func__);
			if (prot[i].start + prot[i].len - pos > len) {
				FL_DBG("but there is some extra at the end\n");
				len -= prot[i].start + prot[i].len - pos;
				pos = prot[i].start + prot[i].len;
			} else {
				FL_DBG("\n");
				len = 0;
			}
		}
		/*
		 * This condition will be true if the range is smaller than
		 * the current range, therefore it should go here!
		 */
		if (pos < prot[i].start && pos + len <= prot[i].start)
			break;
	}

	if (len) {
		int insert_pos = i;
		struct bl_prot_range *new_ranges = ranges->prot;

		FL_DBG("%s: adding 0x%08x..0x%08x\n", __func__, pos, pos + len);

		if (ranges->n_prot == ranges->total_prot) {
			new_ranges = realloc(ranges->prot,
					sizeof(range) * ((ranges->n_prot) + PROT_REALLOC_NUM));
			if (!new_ranges)
				return false;
			ranges->total_prot += PROT_REALLOC_NUM;
		}
		if (insert_pos != ranges->n_prot)
			for (i = ranges->n_prot; i > insert_pos; i--)
				memcpy(&new_ranges[i], &new_ranges[i - 1], sizeof(range));
		range.start = pos;
		range.len = len;
		memcpy(&new_ranges[insert_pos], &range, sizeof(range));
		ranges->prot = new_ranges;
		ranges->n_prot++;
		prot = new_ranges;
	}

	return true;
}

int blocklevel_ecc_protect(struct blocklevel_device *bl, uint32_t start, uint32_t len)
{
	/*
	 * Could implement this at hardware level by having an accessor to the
	 * backend in struct blocklevel_device and as a result do nothing at
	 * this level (although probably not for ecc!)
	 */
	struct bl_prot_range range = { .start = start, .len = len };

	if (len < BYTES_PER_ECC)
		return -1;
	return !insert_bl_prot_range(&bl->ecc_prot, range);
}
