#include "zip.h"

#include <sys/stat.h>

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

#define FOR_REGRESS

typedef enum { SOURCE_TYPE_NONE, SOURCE_TYPE_IN_MEMORY, SOURCE_TYPE_HOLE } source_type_t;

source_type_t source_type = SOURCE_TYPE_NONE;
zip_uint64_t fragment_size = 0;

static int add_nul(int argc, char *argv[]);
static int cancel(int argc, char *argv[]);
static int unchange_one(int argc, char *argv[]);
static int unchange_all(int argc, char *argv[]);
static int zin_close(int argc, char *argv[]);

#define OPTIONS_REGRESS "F:Hm"

#define USAGE_REGRESS " [-Hm] [-F fragment-size]"

#define GETOPT_REGRESS                              \
    case 'H':                                       \
        source_type = SOURCE_TYPE_HOLE;             \
        break;                                      \
    case 'm':                                       \
        source_type = SOURCE_TYPE_IN_MEMORY;        \
        break;                                      \
    case 'F':                                       \
        fragment_size = strtoull(optarg, NULL, 10); \
        break;

/* clang-format off */

#define DISPATCH_REGRESS \
    {"add_nul", 2, "name length", "add NUL bytes", add_nul}, \
    {"cancel", 1, "limit", "cancel writing archive when limit% have been written (calls print_progress)", cancel}, \
    {"unchange", 1, "index", "revert changes for entry", unchange_one}, \
    {"unchange_all", 0, "", "revert all changes", unchange_all}, \
    { "zin_close", 1, "index", "close input zip_source (for internal tests)", zin_close }

/* clang-format on */


zip_t *ziptool_open(const char *archive, int flags, zip_error_t *error, zip_uint64_t offset, zip_uint64_t len);


#include "ziptool.c"


zip_source_t *memory_src = NULL;

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

static zip_t *read_to_memory(const char *archive, int flags, zip_error_t *error, zip_source_t **srcp);
static zip_source_t *source_nul(zip_t *za, zip_uint64_t length);


static int
add_nul(int argc, char *argv[]) {
    zip_source_t *zs;
    zip_uint64_t length = strtoull(argv[1], NULL, 10);

    if ((zs = source_nul(za, length)) == NULL) {
        fprintf(stderr, "can't create zip_source for length: %s\n", zip_strerror(za));
        return -1;
    }

    if (zip_add(za, argv[0], zs) == -1) {
        zip_source_free(zs);
        fprintf(stderr, "can't add file '%s': %s\n", argv[0], zip_strerror(za));
        return -1;
    }
    return 0;
}

static int
unchange_all(int argc, char *argv[]) {
    if (zip_unchange_all(za) < 0) {
        fprintf(stderr, "can't revert changes to archive: %s\n", zip_strerror(za));
        return -1;
    }
    return 0;
}


static int
unchange_one(int argc, char *argv[]) {
    zip_uint64_t idx;

    idx = strtoull(argv[0], NULL, 10);

    if (zip_unchange(za, idx) < 0) {
	fprintf(stderr, "can't revert changes for entry %" PRIu64 ": %s", idx, zip_strerror(za));
	return -1;
    }

    return 0;
}


static int
cancel_callback(zip_t *archive, void *ud) {
    if (progress_userdata.percentage >= progress_userdata.limit) {
        return -1;
    }
    return 0;
}

static int
cancel(int argc, char *argv[]) {
    zip_int64_t percent;
    percent = strtoll(argv[0], NULL, 10);
    if (percent > 100 || percent < 0) {
        fprintf(stderr, "invalid percentage '%" PRId64 "' for cancel (valid: 0 <= x <= 100)\n", percent);
        return -1;
    }
    progress_userdata.limit = ((double)percent) / 100;

    zip_register_cancel_callback_with_state(za, cancel_callback, NULL, NULL);

    /* needs the percentage updates from print_progress */
    print_progress(argc, argv);
    return 0;
}

static int
zin_close(int argc, char *argv[]) {
    zip_uint64_t idx;

    idx = strtoull(argv[0], NULL, 10);
    if (idx >= z_in_count) {
        fprintf(stderr, "invalid argument '%" PRIu64 "', only %u zip sources open\n", idx, z_in_count);
        return -1;
    }
    if (zip_close(z_in[idx]) < 0) {
        fprintf(stderr, "can't close source archive: %s\n", zip_strerror(z_in[idx]));
        return -1;
    }
    z_in[idx] = z_in[z_in_count];
    z_in_count--;

    return 0;
}


static zip_t *
read_hole(const char *archive, int flags, zip_error_t *error) {
    zip_source_t *src = NULL;
    zip_t *zs = NULL;

    if (strcmp(archive, "/dev/stdin") == 0) {
        zip_error_set(error, ZIP_ER_OPNOTSUPP, 0);
        return NULL;
    }

    if ((src = source_hole_create(archive, flags, error)) == NULL || (zs = zip_open_from_source(src, flags, error)) == NULL) {
        zip_source_free(src);
    }

    return zs;
}


static zip_t *
read_to_memory(const char *archive, int flags, zip_error_t *error, zip_source_t **srcp) {
    zip_source_t *src;
    zip_t *zb;
    FILE *fp;

    if (strcmp(archive, "/dev/stdin") == 0) {
        zip_error_set(error, ZIP_ER_OPNOTSUPP, 0);
        return NULL;
    }

    if ((fp = fopen(archive, "rb")) == NULL) {
        if (errno == ENOENT) {
            src = zip_source_buffer_create(NULL, 0, 0, error);
        }
        else {
            zip_error_set(error, ZIP_ER_OPEN, errno);
            return NULL;
        }
    }
    else {
        struct stat st;

        if (fstat(fileno(fp), &st) < 0) {
            fclose(fp);
            zip_error_set(error, ZIP_ER_OPEN, errno);
            return NULL;
        }
        if (fragment_size == 0) {
            char *buf;
            if ((buf = malloc((size_t)st.st_size)) == NULL) {
                fclose(fp);
                zip_error_set(error, ZIP_ER_MEMORY, 0);
                return NULL;
            }
            if (fread(buf, (size_t)st.st_size, 1, fp) < 1) {
                free(buf);
                fclose(fp);
                zip_error_set(error, ZIP_ER_READ, errno);
                return NULL;
            }
            src = zip_source_buffer_create(buf, (zip_uint64_t)st.st_size, 1, error);
            if (src == NULL) {
                free(buf);
            }
        }
        else {
            zip_uint64_t nfragments, i, left;
            zip_buffer_fragment_t *fragments;

            nfragments = ((size_t)st.st_size + fragment_size - 1) / fragment_size;
            if ((fragments = malloc(sizeof(fragments[0]) * nfragments)) == NULL) {
                fclose(fp);
                zip_error_set(error, ZIP_ER_MEMORY, 0);
                return NULL;
            }
            for (i = 0; i < nfragments; i++) {
                left = ZIP_MIN(fragment_size, (size_t)st.st_size - i * fragment_size);
                if ((fragments[i].data = malloc(left)) == NULL) {
#ifndef __clang_analyzer__
                    /* fragments is initialized up to i - 1*/
                    while (--i > 0) {
                        free(fragments[i].data);
                    }
#endif
                    free(fragments);
                    fclose(fp);
                    zip_error_set(error, ZIP_ER_MEMORY, 0);
                    return NULL;
                }
                fragments[i].length = left;
                if (fread(fragments[i].data, left, 1, fp) < 1) {
#ifndef __clang_analyzer__
                    /* fragments is initialized up to i - 1*/
                    while (--i > 0) {
                        free(fragments[i].data);
                    }
#endif
                    free(fragments);
                    fclose(fp);
                    zip_error_set(error, ZIP_ER_READ, errno);
                    return NULL;
                }
            }
            src = zip_source_buffer_fragment_create(fragments, nfragments, 1, error);
            if (src == NULL) {
                for (i = 0; i < nfragments; i++) {
                    free(fragments[i].data);
                }
                free(fragments);
                fclose(fp);
                return NULL;
            }
            free(fragments);
        }
        fclose(fp);
    }
    if (src == NULL) {
        return NULL;
    }
    zb = zip_open_from_source(src, flags, error);
    if (zb == NULL) {
        zip_source_free(src);
        return NULL;
    }
    zip_source_keep(src);
    *srcp = src;
    return zb;
}


typedef struct source_nul {
    zip_error_t error;
    zip_uint64_t length;
    zip_uint64_t offset;
} source_nul_t;

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

    switch (command) {
    case ZIP_SOURCE_CLOSE:
        return 0;

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

    case ZIP_SOURCE_FREE:
        free(ctx);
        return 0;

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

    case ZIP_SOURCE_READ:
        if (length > ZIP_INT64_MAX) {
            zip_error_set(&ctx->error, ZIP_ER_INVAL, 0);
            return -1;
        }

        if (length > ctx->length - ctx->offset) {
            length = ctx->length - ctx->offset;
        }

        memset(data, 0, length);
        ctx->offset += length;
        return (zip_int64_t)length;

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

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

        st->valid |= ZIP_STAT_SIZE;
        st->size = ctx->length;

        return 0;
    }

    case ZIP_SOURCE_SUPPORTS:
        return zip_source_make_command_bitmap(ZIP_SOURCE_CLOSE, ZIP_SOURCE_ERROR, ZIP_SOURCE_FREE, ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_STAT, -1);

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

static zip_source_t *
source_nul(zip_t *zs, zip_uint64_t length) {
    source_nul_t *ctx;
    zip_source_t *src;

    if ((ctx = (source_nul_t *)malloc(sizeof(*ctx))) == NULL) {
        zip_error_set(zip_get_error(zs), ZIP_ER_MEMORY, 0);
        return NULL;
    }

    zip_error_init(&ctx->error);
    ctx->length = length;
    ctx->offset = 0;

    if ((src = zip_source_function(zs, source_nul_cb, ctx)) == NULL) {
        free(ctx);
        return NULL;
    }

    return src;
}


static int
write_memory_src_to_file(const char *archive, zip_source_t *src) {
    zip_stat_t zst;
    char *buf;
    FILE *fp;

    if (zip_source_stat(src, &zst) < 0) {
        fprintf(stderr, "zip_source_stat on buffer failed: %s\n", zip_error_strerror(zip_source_error(src)));
        return -1;
    }
    if (zip_source_open(src) < 0) {
        if (zip_error_code_zip(zip_source_error(src)) == ZIP_ER_DELETED) {
            if (unlink(archive) < 0 && errno != ENOENT) {
                fprintf(stderr, "unlink failed: %s\n", strerror(errno));
                return -1;
            }
            return 0;
        }
        fprintf(stderr, "zip_source_open on buffer failed: %s\n", zip_error_strerror(zip_source_error(src)));
        return -1;
    }
    if ((buf = malloc(zst.size)) == NULL) {
        fprintf(stderr, "malloc failed: %s\n", strerror(errno));
        zip_source_close(src);
        return -1;
    }
    if (zip_source_read(src, buf, zst.size) < (zip_int64_t)zst.size) {
        fprintf(stderr, "zip_source_read on buffer failed: %s\n", zip_error_strerror(zip_source_error(src)));
        zip_source_close(src);
        free(buf);
        return -1;
    }
    zip_source_close(src);
    if ((fp = fopen(archive, "wb")) == NULL) {
        fprintf(stderr, "fopen failed: %s\n", strerror(errno));
        free(buf);
        return -1;
    }
    if (fwrite(buf, zst.size, 1, fp) < 1) {
        fprintf(stderr, "fwrite failed: %s\n", strerror(errno));
        free(buf);
        fclose(fp);
        return -1;
    }
    free(buf);
    if (fclose(fp) != 0) {
        fprintf(stderr, "fclose failed: %s\n", strerror(errno));
        return -1;
    }
    return 0;
}


zip_t *
ziptool_open(const char *archive, int flags, zip_error_t *error, zip_uint64_t offset, zip_uint64_t len) {
    switch (source_type) {
    case SOURCE_TYPE_NONE:
        za = read_from_file(archive, flags, error, offset, len);
        break;

    case SOURCE_TYPE_IN_MEMORY:
        za = read_to_memory(archive, flags, error, &memory_src);
        break;

    case SOURCE_TYPE_HOLE:
        za = read_hole(archive, flags, error);
        break;
    }

    return za;
}


int
ziptool_post_close(const char *archive) {
    if (source_type == SOURCE_TYPE_IN_MEMORY) {
        if (write_memory_src_to_file(archive, memory_src) < 0) {
            return -1;
        }
        zip_source_free(memory_src);
    }

    return 0;
}
