/*
 * Copyright (c) 2013-2016, Intel Corporation
 *
 * 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 Intel Corporation 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.
 */

#include "errcode.h"
#include "file.h"
#include "util.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>

struct text *text_alloc(const char *s)
{
	size_t n, i;
	char **line;
	struct text *t;

	t = calloc(1, sizeof(struct text));
	if (!t)
		return NULL;

	/* If s is NULL or empty, there is nothing to do.  */
	if (!s || *s == '\0')
		return t;

	/* beginning of s is the first line.  */
	t->n = 1;
	t->line = calloc(1, sizeof(*t->line));
	if (!t->line)
		goto error;

	t->line[0] = duplicate_str(s);
	if (!t->line[0])
		goto error;

	/* iterate through all chars and make \r?\n to \0.  */
	n = strlen(t->line[0]);
	for (i = 0; i < n; i++) {
		if (t->line[0][i] == '\r') {
			if (i+1 >= n) {
				/* the file ends with \r.  */
				t->line[0][i] = '\0';
				break;
			}
			/* terminate the line string if it's a line end. */
			if (t->line[0][i+1] == '\n')
				t->line[0][i] = '\0';

		} else if (t->line[0][i] == '\n') {
			/* set newline character always to \0.  */
			t->line[0][i] = '\0';
			if (i+1 >= n) {
				/* the file ends with \n.  */
				break;
			}
			/* increase line pointer buffer.  */
			line = realloc(t->line, (t->n+1) * sizeof(*t->line));
			if (!line)
				goto error;
			t->line = line;
			/* point to the next character after the
			 * newline and increment the number of lines.
			 */
			t->line[t->n++] = &(t->line[0][i+1]);
		}
	}

	return t;

error:
	text_free(t);
	return NULL;
}

void text_free(struct text *t)
{
	if (!t)
		return;

	if (t->line)
		free(t->line[0]);
	free(t->line);
	free(t);
}

int text_line(const struct text *t, char *dest, size_t destlen, size_t n)
{
	if (bug_on(!t))
		return -err_internal;

	if (bug_on(!dest && destlen))
		return -err_internal;

	if (n >= t->n)
		return -err_out_of_range;

	if (!dest)
		return 0;

	if (!destlen)
		return -err_internal;

	strncpy(dest, t->line[n], destlen);

	/* Make sure the string is terminated. */
	dest[destlen-1] = '\0';
	return 0;
}

struct file_list *fl_alloc(void)
{
	return calloc(1, sizeof(struct file_list));
}

void fl_free(struct file_list *fl)
{
	if (!fl)
		return;

	fl_free(fl->next);
	text_free(fl->text);
	free(fl->filename);
	free(fl);
}

/* Appends the @filename to @fl and stores a pointer to the internal
 * text structure in @t.
 *
 * Returns 0 on success; a negative enum errcode otherwise.
 * Returns -err_internal if @fl or @t is the NULL pointer.
 * Returns -err_file_stat if @filename could not be found.
 * Returns -err_file_open if @filename could not be opened.
 * Returns -err_file_read if the content of @filename could not be fully
 * read.
 */
int fl_append(struct file_list *fl, struct text **t, const char *filename)
{
	int errcode;
	FILE *f;
	char *s;
	long pos;
	size_t fsize;
	size_t read;

	if (bug_on(!fl))
		return -err_internal;

	if (bug_on(!t))
		return -err_internal;

	if (bug_on(!filename))
		return -err_internal;

	s = NULL;
	*t = NULL;

	while (fl->next)
		fl = fl->next;

	fl->next = fl_alloc();
	if (!fl->next) {
		errcode = -err_no_mem;
		goto error;
	}

	fl->next->filename = duplicate_str(filename);
	if (!fl->next->filename) {
		errcode = -err_no_mem;
		goto error;
	}

	errno = 0;
	f = fopen(filename, "rb");
	if (!f) {
		fprintf(stderr, "open %s failed: %s\n",
			filename, strerror(errno));
		errcode = -err_file_open;
		goto error;
	}

	errcode = fseek(f, 0, SEEK_END);
	if (errcode) {
		fprintf(stderr, "%s: failed to seek end: %s\n",
			filename, strerror(errno));
		errcode = -err_file_size;
		goto error_file;
	}

	pos = ftell(f);
	if (pos < 0) {
		fprintf(stderr, "%s: failed to determine file size: %s\n",
			filename, strerror(errno));
		errcode = -err_file_size;
		goto error_file;
	}
	fsize = (size_t) pos;

	errcode = fseek(f, 0, SEEK_SET);
	if (errcode) {
		fprintf(stderr, "%s: failed to seek begin: %s\n",
			filename, strerror(errno));
		errcode = -err_file_size;
		goto error_file;
	}

	s = calloc(fsize+1, 1); /* size + 1: space for last null byte.  */
	if (!s) {
		errcode = -err_no_mem;
		goto error_file;
	}

	read = fread(s, 1, fsize, f);
	fclose(f);
	if (read != fsize) {
		fprintf(stderr, "read %s failed\n", filename);
		errcode = -err_file_read;
		goto error;
	}

	*t = text_alloc(s);
	if (!*t) {
		errcode = -err_no_mem;
		goto error;
	}

	free(s);
	fl->next->text = *t;

	return 0;

error_file:
	fclose(f);
error:
	/* filename is closed after reading before handling error.  */
	fl_free(fl->next);
	fl->next = NULL;
	free(s);
	text_free(*t);
	*t = NULL;
	return errcode;
}

int fl_getline(struct file_list *fl, char *dest, size_t destlen,
	       const char *filename, size_t n)
{
	int errcode;
	const struct text *t;

	if (bug_on(!fl))
		return -err_internal;

	errcode = fl_gettext(fl, &t, filename);
	if (errcode < 0)
		return errcode;

	return text_line(t, dest, destlen, n);
}

int fl_gettext(struct file_list *fl, const struct text **t,
	       const char *filename)
{
	struct text *tmp;
	int errcode;

	if (bug_on(!fl))
		return -err_internal;

	if (bug_on(!t))
		return -err_internal;

	if (bug_on(!filename))
		return -err_internal;

	while (fl->next) {
		fl = fl->next;
		if (strcmp(fl->filename, filename) == 0) {
			*t = fl->text;
			return 0;
		}
	}
	errcode = fl_append(fl, &tmp, filename);
	if (errcode < 0)
		return errcode;

	*t = tmp;
	return 0;
}
