/*
 source_hole.c -- source for handling huge files that are mostly NULs
 Copyright (C) 2014-2019 Dieter Baron and Thomas Klausner

 This file is part of libzip, a library to manipulate ZIP archives.
 The authors can be contacted at <libzip@nih.at>

 Redistribution and use in source and binary forms, with or without
 modification, are permitted provided that the following conditions
 are met:
 1. Redistributions of source code must retain the above copyright
 notice, this list of conditions and the following disclaimer.
 2. 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.
 3. The names of the authors may not be used to endorse or promote
 products derived from this software without specific prior
 written permission.

 THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``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 AUTHORS 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 <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "zip.h"

/* public API */

zip_source_t *source_hole_create(const char *, int flags, zip_error_t *);


#ifndef EFTYPE
#define EFTYPE EINVAL
#endif


#define MY_MIN(a, b) ((a) < (b) ? (a) : (b))

#define FRAGMENT_SIZE (8 * 1024)

#define MARK_BEGIN "NiH0"
#define MARK_DATA "NiH1"
#define MARK_NUL "NiH2"


typedef struct buffer {
    zip_uint64_t fragment_size;
    zip_uint8_t **fragment;
    zip_uint64_t nfragments;
    zip_uint64_t size;
    zip_uint64_t offset;
} buffer_t;

static void buffer_free(buffer_t *buffer);
static buffer_t *buffer_from_file(const char *fname, int flags, zip_error_t *error);
static buffer_t *buffer_new(void);
static zip_int64_t buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length, zip_error_t *error);
static int buffer_read_file(buffer_t *buffer, FILE *f, zip_error_t *error);
static zip_int64_t buffer_seek(buffer_t *buffer, void *data, zip_uint64_t length, zip_error_t *error);
static int buffer_to_file(buffer_t *buffer, const char *fname, zip_error_t *error);
static zip_int64_t buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error);
static zip_uint64_t get_u64(const zip_uint8_t *b);
static int only_nul(const zip_uint8_t *data, zip_uint64_t length);
static int write_nuls(zip_uint64_t n, FILE *f);
static int write_u64(zip_uint64_t u64, FILE *f);


typedef struct hole {
    zip_error_t error;
    char *fname;
    buffer_t *in;
    buffer_t *out;
} hole_t;

static hole_t *hole_new(const char *fname, int flags, zip_error_t *error);
static zip_int64_t source_hole_cb(void *ud, void *data, zip_uint64_t length, zip_source_cmd_t command);


zip_source_t *
source_hole_create(const char *fname, int flags, zip_error_t *error) {
    hole_t *ud = hole_new(fname, flags, error);

    if (ud == NULL) {
	return NULL;
    }
    return zip_source_function_create(source_hole_cb, ud, error);
}


static void
buffer_free(buffer_t *buffer) {
    zip_uint64_t i;

    if (buffer == NULL) {
	return;
    }

    if (buffer->fragment) {
	for (i = 0; i < buffer->nfragments; i++) {
	    free(buffer->fragment[i]);
	}
	free(buffer->fragment);
    }
    free(buffer);
}


static buffer_t *
buffer_from_file(const char *fname, int flags, zip_error_t *error) {
    buffer_t *buffer;
    FILE *f;

    if ((buffer = buffer_new()) == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    if ((flags & ZIP_TRUNCATE) == 0) {
	if ((f = fopen(fname, "rb")) == NULL) {
	    if (!(errno == ENOENT && (flags & ZIP_CREATE))) {
		buffer_free(buffer);
		return NULL;
	    }
	}
	else {
	    if (buffer_read_file(buffer, f, error) < 0) {
		buffer_free(buffer);
		fclose(f);
		return NULL;
	    }
	    fclose(f);
	}
    }

    return buffer;
}


static buffer_t *
buffer_new(void) {
    buffer_t *buffer;

    if ((buffer = (buffer_t *)malloc(sizeof(*buffer))) == NULL) {
	return NULL;
    }

    buffer->fragment = NULL;
    buffer->nfragments = 0;
    buffer->fragment_size = FRAGMENT_SIZE;
    buffer->size = 0;
    buffer->offset = 0;

    return buffer;
}


static zip_int64_t
buffer_read(buffer_t *buffer, zip_uint8_t *data, zip_uint64_t length, zip_error_t *error) {
    zip_uint64_t n, i, fragment_offset;

    length = MY_MIN(length, buffer->size - buffer->offset);

    if (length == 0) {
	return 0;
    }
    if (length > ZIP_INT64_MAX) {
	return -1;
    }

    i = buffer->offset / buffer->fragment_size;
    fragment_offset = buffer->offset % buffer->fragment_size;
    n = 0;
    while (n < length) {
	zip_uint64_t left = MY_MIN(length - n, buffer->fragment_size - fragment_offset);

	if (buffer->fragment[i]) {
	    memcpy(data + n, buffer->fragment[i] + fragment_offset, left);
	}
	else {
	    memset(data + n, 0, left);
	}

	n += left;
	i++;
	fragment_offset = 0;
    }

    buffer->offset += n;
    return (zip_int64_t)n;
}


static int
buffer_read_file(buffer_t *buffer, FILE *f, zip_error_t *error) {
    zip_uint8_t b[20];
    zip_uint64_t i;

    if (fread(b, 20, 1, f) != 1) {
	zip_error_set(error, ZIP_ER_READ, errno);
	return -1;
    }

    if (memcmp(b, MARK_BEGIN, 4) != 0) {
	zip_error_set(error, ZIP_ER_READ, EFTYPE);
	return -1;
    }

    buffer->fragment_size = get_u64(b + 4);
    buffer->size = get_u64(b + 12);

    if (buffer->size + buffer->fragment_size < buffer->size) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return -1;
    }
    buffer->nfragments = (buffer->size + buffer->fragment_size - 1) / buffer->fragment_size;
    if ((buffer->nfragments > SIZE_MAX / sizeof(buffer->fragment[0])) || ((buffer->fragment = (zip_uint8_t **)malloc(sizeof(buffer->fragment[0]) * buffer->nfragments)) == NULL)) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return -1;
    }

    for (i = 0; i < buffer->nfragments; i++) {
	buffer->fragment[i] = NULL;
    }

    i = 0;
    while (i < buffer->nfragments) {
	if (fread(b, 4, 1, f) != 1) {
	    zip_error_set(error, ZIP_ER_READ, errno);
	    return -1;
	}

	if (memcmp(b, MARK_DATA, 4) == 0) {
	    if (buffer->fragment_size > SIZE_MAX) {
		zip_error_set(error, ZIP_ER_MEMORY, 0);
		return -1;
	    }
	    if ((buffer->fragment[i] = (zip_uint8_t *)malloc(buffer->fragment_size)) == NULL) {
		zip_error_set(error, ZIP_ER_MEMORY, 0);
		return -1;
	    }
	    if (fread(buffer->fragment[i], buffer->fragment_size, 1, f) != 1) {
		zip_error_set(error, ZIP_ER_READ, errno);
		return -1;
	    }
	    i++;
	}
	else if (memcmp(b, MARK_NUL, 4) == 0) {
	    if (fread(b, 8, 1, f) != 1) {
		zip_error_set(error, ZIP_ER_READ, errno);
		return -1;
	    }
	    i += get_u64(b);
	}
	else {
	    zip_error_set(error, ZIP_ER_READ, EFTYPE);
	    return -1;
	}
    }

    return 0;
}

static zip_int64_t
buffer_seek(buffer_t *buffer, void *data, zip_uint64_t length, zip_error_t *error) {
    zip_int64_t new_offset = zip_source_seek_compute_offset(buffer->offset, buffer->size, data, length, error);

    if (new_offset < 0) {
	return -1;
    }

    buffer->offset = (zip_uint64_t)new_offset;
    return 0;
}


static int
buffer_to_file(buffer_t *buffer, const char *fname, zip_error_t *error) {
    FILE *f = fopen(fname, "wb");
    zip_uint64_t i;
    zip_uint64_t nul_run;

    if (f == NULL) {
	zip_error_set(error, ZIP_ER_OPEN, errno);
	return -1;
    }

    fwrite(MARK_BEGIN, 4, 1, f);
    write_u64(buffer->fragment_size, f);
    write_u64(buffer->size, f);

    nul_run = 0;
    for (i = 0; i * buffer->fragment_size < buffer->size; i++) {
	if (buffer->fragment[i] == NULL || only_nul(buffer->fragment[i], buffer->fragment_size)) {
	    nul_run++;
	}
	else {
	    if (nul_run > 0) {
		write_nuls(nul_run, f);
		nul_run = 0;
	    }
	    fwrite(MARK_DATA, 4, 1, f);

	    fwrite(buffer->fragment[i], 1, buffer->fragment_size, f);
	}
    }

    if (nul_run > 0) {
	write_nuls(nul_run, f);
    }

    if (fclose(f) != 0) {
	zip_error_set(error, ZIP_ER_WRITE, errno);
	return -1;
    }

    return 0;
}


static zip_int64_t
buffer_write(buffer_t *buffer, const zip_uint8_t *data, zip_uint64_t length, zip_error_t *error) {
    zip_uint8_t **fragment;
    if (buffer->offset + length > buffer->nfragments * buffer->fragment_size) {
	zip_uint64_t needed_fragments = (buffer->offset + length + buffer->fragment_size - 1) / buffer->fragment_size;
	zip_uint64_t new_capacity = buffer->nfragments;
	zip_uint64_t i;

	if (new_capacity == 0) {
	    new_capacity = 4;
	}
	while (new_capacity < needed_fragments) {
	    new_capacity *= 2;
	}

	fragment = realloc(buffer->fragment, new_capacity * sizeof(*fragment));

	if (fragment == NULL) {
	    zip_error_set(error, ZIP_ER_MEMORY, 0);
	    return -1;
	}

	for (i = buffer->nfragments; i < new_capacity; i++) {
	    fragment[i] = NULL;
	}

	buffer->fragment = fragment;
	buffer->nfragments = new_capacity;
    }

    if (!only_nul(data, length)) {
	zip_uint64_t idx, n, fragment_offset;

	idx = buffer->offset / buffer->fragment_size;
	fragment_offset = buffer->offset % buffer->fragment_size;
	n = 0;

	while (n < length) {
	    zip_uint64_t left = MY_MIN(length - n, buffer->fragment_size - fragment_offset);

	    if (buffer->fragment[idx] == NULL) {
		if ((buffer->fragment[idx] = (zip_uint8_t *)malloc(buffer->fragment_size)) == NULL) {
		    zip_error_set(error, ZIP_ER_MEMORY, 0);
		    return -1;
		}
		memset(buffer->fragment[idx], 0, buffer->fragment_size);
	    }
	    memcpy(buffer->fragment[idx] + fragment_offset, data + n, left);

	    n += left;
	    idx++;
	    fragment_offset = 0;
	}
    }

    buffer->offset += length;
    if (buffer->offset > buffer->size) {
	buffer->size = buffer->offset;
    }

    return (zip_int64_t)length;
}


static zip_uint64_t
get_u64(const zip_uint8_t *b) {
    zip_uint64_t i;

    i = (zip_uint64_t)b[0] << 56 | (zip_uint64_t)b[1] << 48 | (zip_uint64_t)b[2] << 40 | (zip_uint64_t)b[3] << 32 | (zip_uint64_t)b[4] << 24 | (zip_uint64_t)b[5] << 16 | (zip_uint64_t)b[6] << 8 | (zip_uint64_t)b[7];

    return i;
}


static int
only_nul(const zip_uint8_t *data, zip_uint64_t length) {
    zip_uint64_t i;

    for (i = 0; i < length; i++) {
	if (data[i] != '\0') {
	    return 0;
	}
    }

    return 1;
}


static int
write_nuls(zip_uint64_t n, FILE *f) {
    if (fwrite(MARK_NUL, 4, 1, f) != 1) {
	return -1;
    }
    return write_u64(n, f);
}


static int
write_u64(zip_uint64_t u64, FILE *f) {
    zip_uint8_t b[8];

    b[0] = (zip_uint8_t)((u64 >> 56) & 0xff);
    b[1] = (zip_uint8_t)((u64 >> 48) & 0xff);
    b[2] = (zip_uint8_t)((u64 >> 40) & 0xff);
    b[3] = (zip_uint8_t)((u64 >> 32) & 0xff);
    b[4] = (zip_uint8_t)((u64 >> 24) & 0xff);
    b[5] = (zip_uint8_t)((u64 >> 16) & 0xff);
    b[6] = (zip_uint8_t)((u64 >> 8) & 0xff);
    b[7] = (zip_uint8_t)(u64 & 0xff);

    return fwrite(b, 8, 1, f) == 1 ? 0 : -1;
}


static void
hole_free(hole_t *hole) {
    if (hole == NULL) {
	return;
    }
    zip_error_fini(&hole->error);
    buffer_free(hole->in);
    buffer_free(hole->out);
    free(hole->fname);
    free(hole);
}


static hole_t *
hole_new(const char *fname, int flags, zip_error_t *error) {
    hole_t *ctx = (hole_t *)malloc(sizeof(*ctx));

    if (ctx == NULL) {
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    if ((ctx->fname = strdup(fname)) == NULL) {
	free(ctx);
	zip_error_set(error, ZIP_ER_MEMORY, 0);
	return NULL;
    }

    if ((ctx->in = buffer_from_file(fname, flags, error)) == NULL) {
	free(ctx);
	return NULL;
    }

    zip_error_init(&ctx->error);
    ctx->out = NULL;

    return ctx;
}


static zip_int64_t
source_hole_cb(void *ud, void *data, zip_uint64_t length, zip_source_cmd_t command) {
    hole_t *ctx = (hole_t *)ud;

    switch (command) {
    case ZIP_SOURCE_BEGIN_WRITE:
	ctx->out = buffer_new();
	return 0;

    case ZIP_SOURCE_CLOSE:
	return 0;

    case ZIP_SOURCE_COMMIT_WRITE:
	if (buffer_to_file(ctx->out, ctx->fname, &ctx->error) < 0) {
	    return -1;
	}
	buffer_free(ctx->in);
	ctx->in = ctx->out;
	ctx->out = NULL;
	return 0;

    case ZIP_SOURCE_ERROR:
	return zip_error_to_data(&ctx->error, data, length);

    case ZIP_SOURCE_FREE:
	hole_free(ctx);
	return 0;

    case ZIP_SOURCE_OPEN:
	ctx->in->offset = 0;
	return 0;

    case ZIP_SOURCE_READ:
	return buffer_read(ctx->in, data, length, &ctx->error);

    case ZIP_SOURCE_REMOVE:
	buffer_free(ctx->in);
	ctx->in = buffer_new();
	buffer_free(ctx->out);
	ctx->out = NULL;
	(void)remove(ctx->fname);
	return 0;

    case ZIP_SOURCE_ROLLBACK_WRITE:
	buffer_free(ctx->out);
	ctx->out = NULL;
	return 0;

    case ZIP_SOURCE_SEEK:
	return buffer_seek(ctx->in, data, length, &ctx->error);

    case ZIP_SOURCE_SEEK_WRITE:
	return buffer_seek(ctx->out, data, length, &ctx->error);

    case ZIP_SOURCE_STAT: {
	zip_stat_t *st = ZIP_SOURCE_GET_ARGS(zip_stat_t, data, length, &ctx->error);

	if (st == NULL) {
	    return -1;
	}

	/* TODO: return ENOENT if fname doesn't exist */

	st->valid |= ZIP_STAT_SIZE;
	st->size = ctx->in->size;
	return 0;
    }

    case ZIP_SOURCE_TELL:
	return (zip_int64_t)ctx->in->offset;

    case ZIP_SOURCE_TELL_WRITE:
	return (zip_int64_t)ctx->out->offset;

    case ZIP_SOURCE_WRITE:
	return buffer_write(ctx->out, data, length, &ctx->error);

    case ZIP_SOURCE_SUPPORTS:
	return zip_source_make_command_bitmap(ZIP_SOURCE_BEGIN_WRITE, ZIP_SOURCE_COMMIT_WRITE, ZIP_SOURCE_CLOSE, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_REMOVE, ZIP_SOURCE_ROLLBACK_WRITE, ZIP_SOURCE_SEEK, ZIP_SOURCE_SEEK_WRITE, ZIP_SOURCE_STAT, ZIP_SOURCE_TELL, ZIP_SOURCE_TELL_WRITE, ZIP_SOURCE_WRITE, -1);

    default:
	zip_error_set(&ctx->error, ZIP_ER_OPNOTSUPP, 0);
	return -1;
    }
}
