/*
 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 <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;
    }
}
