/**
 * Copyright © 2016 IBM Corporation
 *
 * 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 <endian.h>
#include <err.h>
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <sys/mman.h>

#include <linux/types.h>

#include "console-server.h"

struct log_handler {
	struct handler	handler;
	struct console	*console;
	int		fd;
	size_t		size;
	size_t		maxsize;
	int		pagesize;
};


static const char *default_filename = LOCALSTATEDIR "/log/obmc-console.log";

static const size_t logsize = 16 * 1024;

static struct log_handler *to_log_handler(struct handler *handler)
{
	return container_of(handler, struct log_handler, handler);
}

static int log_init(struct handler *handler, struct console *console,
		struct config *config __attribute__((unused)))
{
	struct log_handler *lh = to_log_handler(handler);
	const char *filename;
	int rc;

	lh->console = console;
	lh->maxsize = logsize;
	lh->pagesize = 4096;
	lh->size = 0;

	filename = config_get_value(config, "logfile");
	if (!filename)
		filename = default_filename;

	lh->fd = open(filename, O_RDWR | O_CREAT, 0644);
	if (lh->fd < 0) {
		warn("Can't open log buffer file %s", filename);
		return -1;
	}
	rc = ftruncate(lh->fd, 0);
	if (rc) {
		warn("Can't truncate file %s", filename);
		close(lh->fd);
		return -1;
	}

	return 0;
}

static int log_trim(struct log_handler *lh, size_t space)
{
	int rc, n_shift_pages, shift_len, shift_start;
	off_t pos;
	void *buf;

	pos = lseek(lh->fd, 0, SEEK_CUR);

	n_shift_pages = (space + lh->pagesize - 1) / lh->pagesize;
	shift_start = n_shift_pages * lh->pagesize;
	shift_len = pos - (n_shift_pages * lh->pagesize);

	buf = mmap(NULL, pos, PROT_READ | PROT_WRITE, MAP_SHARED, lh->fd, 0);
	if (buf == MAP_FAILED)
		return -1;

	memmove(buf, buf + shift_start, shift_len);

	munmap(buf, pos);

	lh->size = shift_len;
	rc = ftruncate(lh->fd, lh->size);
	if (rc)
		warn("failed to truncate file");
	lseek(lh->fd, 0, SEEK_END);

	return 0;

}

static int log_data(struct handler *handler, uint8_t *buf, size_t len)
{
	struct log_handler *lh = to_log_handler(handler);
	int rc;

	if (len > lh->maxsize) {
		buf += len - lh->maxsize;
		len = lh->maxsize;
	}

	if (lh->size + len > lh->maxsize) {
		rc = log_trim(lh, len);
		if (rc)
			return rc;
	}

	rc = write_buf_to_fd(lh->fd, buf, len);
	if (rc)
		return rc;

	lh->size += len;

	return 0;
}

static void log_fini(struct handler *handler)
{
	struct log_handler *lh = to_log_handler(handler);
	close(lh->fd);
}

static struct log_handler log_handler = {
	.handler = {
		.name		= "log",
		.init		= log_init,
		.data_in	= log_data,
		.fini		= log_fini,
	},
};

console_register_handler(&log_handler.handler);

