/*
  zip_close.c -- close zip archive and update changes
  Copyright (C) 1999-2020 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 "zipint.h"

#include <stdio.h>
#include <stdlib.h>
#ifdef _WIN32
#include <fcntl.h>
#include <io.h>
#endif


static int add_data(zip_t *, zip_source_t *, zip_dirent_t *, zip_uint32_t);
static int copy_data(zip_t *, zip_uint64_t);
static int copy_source(zip_t *, zip_source_t *, zip_int64_t);
static int write_cdir(zip_t *, const zip_filelist_t *, zip_uint64_t);
static int write_data_descriptor(zip_t *za, const zip_dirent_t *dirent, int is_zip64);

ZIP_EXTERN int
zip_close(zip_t *za) {
    zip_uint64_t i, j, survivors, unchanged_offset;
    zip_int64_t off;
    int error;
    zip_filelist_t *filelist;
    int changed;

    if (za == NULL)
	return -1;

    changed = _zip_changed(za, &survivors);

    /* don't create zip files with no entries */
    if (survivors == 0) {
	if ((za->open_flags & ZIP_TRUNCATE) || changed) {
	    if (zip_source_remove(za->src) < 0) {
		if (!((zip_error_code_zip(zip_source_error(za->src)) == ZIP_ER_REMOVE) && (zip_error_code_system(zip_source_error(za->src)) == ENOENT))) {
		    _zip_error_set_from_source(&za->error, za->src);
		    return -1;
		}
	    }
	}
	zip_discard(za);
	return 0;
    }

    if (!changed) {
	zip_discard(za);
	return 0;
    }

    if (survivors > za->nentry) {
	zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	return -1;
    }

    if ((filelist = (zip_filelist_t *)malloc(sizeof(filelist[0]) * (size_t)survivors)) == NULL)
	return -1;

    unchanged_offset = ZIP_UINT64_MAX;
    /* create list of files with index into original archive  */
    for (i = j = 0; i < za->nentry; i++) {
	if (za->entry[i].orig != NULL && ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) {
	    unchanged_offset = ZIP_MIN(unchanged_offset, za->entry[i].orig->offset);
	}
	if (za->entry[i].deleted) {
	    continue;
	}

	if (j >= survivors) {
	    free(filelist);
	    zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	    return -1;
	}

	filelist[j].idx = i;
	j++;
    }
    if (j < survivors) {
	free(filelist);
	zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	return -1;
    }

    if ((zip_source_supports(za->src) & ZIP_SOURCE_MAKE_COMMAND_BITMASK(ZIP_SOURCE_BEGIN_WRITE_CLONING)) == 0) {
	unchanged_offset = 0;
    }
    else {
	if (unchanged_offset == ZIP_UINT64_MAX) {
	    /* we're keeping all file data, find the end of the last one */
	    zip_uint64_t last_index = ZIP_UINT64_MAX;
	    unchanged_offset = 0;

	    for (i = 0; i < za->nentry; i++) {
		if (za->entry[i].orig != NULL) {
		    if (za->entry[i].orig->offset >= unchanged_offset) {
			unchanged_offset = za->entry[i].orig->offset;
			last_index = i;
		    }
		}
	    }
	    if (last_index != ZIP_UINT64_MAX) {
		if ((unchanged_offset = _zip_file_get_end(za, last_index, &za->error)) == 0) {
		    free(filelist);
		    return -1;
		}
	    }
	}
	if (unchanged_offset > 0) {
	    if (zip_source_begin_write_cloning(za->src, unchanged_offset) < 0) {
		/* cloning not supported, need to copy everything */
		unchanged_offset = 0;
	    }
	}
    }
    if (unchanged_offset == 0) {
	if (zip_source_begin_write(za->src) < 0) {
	    _zip_error_set_from_source(&za->error, za->src);
	    free(filelist);
	    return -1;
	}
    }

    if (_zip_progress_start(za->progress) != 0) {
	zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
	zip_source_rollback_write(za->src);
	free(filelist);
	return -1;
    }
    error = 0;
    for (j = 0; j < survivors; j++) {
	int new_data;
	zip_entry_t *entry;
	zip_dirent_t *de;

	if (_zip_progress_subrange(za->progress, (double)j / (double)survivors, (double)(j + 1) / (double)survivors) != 0) {
	    zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
	    error = 1;
	    break;
	}

	i = filelist[j].idx;
	entry = za->entry + i;

	if (entry->orig != NULL && entry->orig->offset < unchanged_offset) {
	    /* already implicitly copied by cloning */
	    continue;
	}

	new_data = (ZIP_ENTRY_DATA_CHANGED(entry) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_COMP_METHOD) || ZIP_ENTRY_CHANGED(entry, ZIP_DIRENT_ENCRYPTION_METHOD));

	/* create new local directory entry */
	if (entry->changes == NULL) {
	    if ((entry->changes = _zip_dirent_clone(entry->orig)) == NULL) {
		zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
		error = 1;
		break;
	    }
	}
	de = entry->changes;

	if (_zip_read_local_ef(za, i) < 0) {
	    error = 1;
	    break;
	}

	if ((off = zip_source_tell_write(za->src)) < 0) {
	    _zip_error_set_from_source(&za->error, za->src);
	    error = 1;
	    break;
	}
	de->offset = (zip_uint64_t)off;

	if (new_data) {
	    zip_source_t *zs;

	    zs = NULL;
	    if (!ZIP_ENTRY_DATA_CHANGED(entry)) {
		if ((zs = _zip_source_zip_new(za, za, i, ZIP_FL_UNCHANGED, 0, 0, NULL)) == NULL) {
		    error = 1;
		    break;
		}
	    }

	    /* add_data writes dirent */
	    if (add_data(za, zs ? zs : entry->source, de, entry->changes ? entry->changes->changed : 0) < 0) {
		error = 1;
		if (zs)
		    zip_source_free(zs);
		break;
	    }
	    if (zs)
		zip_source_free(zs);
	}
	else {
	    zip_uint64_t offset;

	    if (de->encryption_method != ZIP_EM_TRAD_PKWARE) {
		/* when copying data, all sizes are known -> no data descriptor needed */
		/* except for PKWare encryption, where removing the data descriptor breaks password validation */
		de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
	    }
	    if (_zip_dirent_write(za, de, ZIP_FL_LOCAL) < 0) {
		error = 1;
		break;
	    }
	    if ((offset = _zip_file_get_offset(za, i, &za->error)) == 0) {
		error = 1;
		break;
	    }
	    if (zip_source_seek(za->src, (zip_int64_t)offset, SEEK_SET) < 0) {
		_zip_error_set_from_source(&za->error, za->src);
		error = 1;
		break;
	    }
	    if (copy_data(za, de->comp_size) < 0) {
		error = 1;
		break;
	    }

	    if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
		if (write_data_descriptor(za, de, _zip_dirent_needs_zip64(de, 0)) < 0) {
		    error = 1;
		    break;
		}
	    }
	}
    }

    if (!error) {
	if (write_cdir(za, filelist, survivors) < 0)
	    error = 1;
    }

    free(filelist);

    if (!error) {
	if (zip_source_commit_write(za->src) != 0) {
	    _zip_error_set_from_source(&za->error, za->src);
	    error = 1;
	}
	_zip_progress_end(za->progress);
    }

    if (error) {
	zip_source_rollback_write(za->src);
	return -1;
    }

    zip_discard(za);

    return 0;
}


static int
add_data(zip_t *za, zip_source_t *src, zip_dirent_t *de, zip_uint32_t changed) {
    zip_int64_t offstart, offdata, offend, data_length;
    zip_stat_t st;
    zip_file_attributes_t attributes;
    zip_source_t *src_final, *src_tmp;
    int ret;
    int is_zip64;
    zip_flags_t flags;
    bool needs_recompress, needs_decompress, needs_crc, needs_compress, needs_reencrypt, needs_decrypt, needs_encrypt;

    if (zip_source_stat(src, &st) < 0) {
	_zip_error_set_from_source(&za->error, src);
	return -1;
    }

    if ((st.valid & ZIP_STAT_COMP_METHOD) == 0) {
	st.valid |= ZIP_STAT_COMP_METHOD;
	st.comp_method = ZIP_CM_STORE;
    }

    if (ZIP_CM_IS_DEFAULT(de->comp_method) && st.comp_method != ZIP_CM_STORE)
	de->comp_method = st.comp_method;
    else if (de->comp_method == ZIP_CM_STORE && (st.valid & ZIP_STAT_SIZE)) {
	st.valid |= ZIP_STAT_COMP_SIZE;
	st.comp_size = st.size;
    }
    else {
	/* we'll recompress */
	st.valid &= ~ZIP_STAT_COMP_SIZE;
    }

    if ((st.valid & ZIP_STAT_ENCRYPTION_METHOD) == 0) {
	st.valid |= ZIP_STAT_ENCRYPTION_METHOD;
	st.encryption_method = ZIP_EM_NONE;
    }

    flags = ZIP_EF_LOCAL;

    if ((st.valid & ZIP_STAT_SIZE) == 0) {
	flags |= ZIP_FL_FORCE_ZIP64;
	data_length = -1;
    }
    else {
	de->uncomp_size = st.size;
	/* this is technically incorrect (copy_source counts compressed data), but it's the best we have */
	data_length = (zip_int64_t)st.size;

	if ((st.valid & ZIP_STAT_COMP_SIZE) == 0) {
	    zip_uint64_t max_compressed_size;
	    zip_uint16_t compression_method = ZIP_CM_ACTUAL(de->comp_method);

	    if (compression_method == ZIP_CM_STORE) {
		max_compressed_size = st.size;
	    }
	    else {
		zip_compression_algorithm_t *algorithm = _zip_get_compression_algorithm(compression_method, true);
		if (algorithm == NULL) {
		    max_compressed_size = ZIP_UINT64_MAX;
		}
		else {
		    max_compressed_size = algorithm->maximum_compressed_size(st.size);
		}
	    }

	    if (max_compressed_size > 0xffffffffu) {
		flags |= ZIP_FL_FORCE_ZIP64;
	    }
	}
	else {
	    de->comp_size = st.comp_size;
	    data_length = (zip_int64_t)st.comp_size;
	}
    }

    if ((offstart = zip_source_tell_write(za->src)) < 0) {
	_zip_error_set_from_source(&za->error, za->src);
	return -1;
    }

    /* as long as we don't support non-seekable output, clear data descriptor bit */
    de->bitflags &= (zip_uint16_t)~ZIP_GPBF_DATA_DESCRIPTOR;
    if ((is_zip64 = _zip_dirent_write(za, de, flags)) < 0) {
	return -1;
    }

    needs_recompress = st.comp_method != ZIP_CM_ACTUAL(de->comp_method);
    needs_decompress = needs_recompress && (st.comp_method != ZIP_CM_STORE);
    /* in these cases we can compute the CRC ourselves, so we do */
    needs_crc = (st.comp_method == ZIP_CM_STORE) || needs_decompress;
    needs_compress = needs_recompress && (de->comp_method != ZIP_CM_STORE);

    needs_reencrypt = needs_recompress || (de->changed & ZIP_DIRENT_PASSWORD) || (de->encryption_method != st.encryption_method);
    needs_decrypt = needs_reencrypt && (st.encryption_method != ZIP_EM_NONE);
    needs_encrypt = needs_reencrypt && (de->encryption_method != ZIP_EM_NONE);

    src_final = src;
    zip_source_keep(src_final);

    if (needs_decrypt) {
	zip_encryption_implementation impl;

	if ((impl = _zip_get_encryption_implementation(st.encryption_method, ZIP_CODEC_DECODE)) == NULL) {
	    zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
	    zip_source_free(src_final);
	    return -1;
	}
	if ((src_tmp = impl(za, src_final, st.encryption_method, ZIP_CODEC_DECODE, za->default_password)) == NULL) {
	    /* error set by impl */
	    zip_source_free(src_final);
	    return -1;
	}

	zip_source_free(src_final);
	src_final = src_tmp;
    }

    if (needs_decompress) {
	if ((src_tmp = zip_source_decompress(za, src_final, st.comp_method)) == NULL) {
	    zip_source_free(src_final);
	    return -1;
	}

	zip_source_free(src_final);
	src_final = src_tmp;
    }

    if (needs_crc) {
	if ((src_tmp = zip_source_crc(za, src_final, 0)) == NULL) {
	    zip_source_free(src_final);
	    return -1;
	}

	zip_source_free(src_final);
	src_final = src_tmp;
    }

    if (needs_compress) {
	if ((src_tmp = zip_source_compress(za, src_final, de->comp_method, de->compression_level)) == NULL) {
	    zip_source_free(src_final);
	    return -1;
	}

	zip_source_free(src_final);
	src_final = src_tmp;
    }


    if (needs_encrypt) {
	zip_encryption_implementation impl;
	const char *password = NULL;

	if (de->password) {
	    password = de->password;
	}
	else if (za->default_password) {
	    password = za->default_password;
	}

	if ((impl = _zip_get_encryption_implementation(de->encryption_method, ZIP_CODEC_ENCODE)) == NULL) {
	    zip_error_set(&za->error, ZIP_ER_ENCRNOTSUPP, 0);
	    zip_source_free(src_final);
	    return -1;
	}
	if ((src_tmp = impl(za, src_final, de->encryption_method, ZIP_CODEC_ENCODE, password)) == NULL) {
	    /* error set by impl */
	    zip_source_free(src_final);
	    return -1;
	}
	if (de->encryption_method == ZIP_EM_TRAD_PKWARE) {
	    de->bitflags |= ZIP_GPBF_DATA_DESCRIPTOR;
	}

	zip_source_free(src_final);
	src_final = src_tmp;
    }


    if ((offdata = zip_source_tell_write(za->src)) < 0) {
	_zip_error_set_from_source(&za->error, za->src);
	return -1;
    }

    ret = copy_source(za, src_final, data_length);

    if (zip_source_stat(src_final, &st) < 0) {
	_zip_error_set_from_source(&za->error, src_final);
	ret = -1;
    }

    if (zip_source_get_file_attributes(src_final, &attributes) != 0) {
	_zip_error_set_from_source(&za->error, src_final);
	ret = -1;
    }

    zip_source_free(src_final);

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

    if ((offend = zip_source_tell_write(za->src)) < 0) {
	_zip_error_set_from_source(&za->error, za->src);
	return -1;
    }

    if (zip_source_seek_write(za->src, offstart, SEEK_SET) < 0) {
	_zip_error_set_from_source(&za->error, za->src);
	return -1;
    }

    if ((st.valid & (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) != (ZIP_STAT_COMP_METHOD | ZIP_STAT_CRC | ZIP_STAT_SIZE)) {
	zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	return -1;
    }

    if ((de->changed & ZIP_DIRENT_LAST_MOD) == 0) {
	if (st.valid & ZIP_STAT_MTIME)
	    de->last_mod = st.mtime;
	else
	    time(&de->last_mod);
    }
    de->comp_method = st.comp_method;
    de->crc = st.crc;
    de->uncomp_size = st.size;
    de->comp_size = (zip_uint64_t)(offend - offdata);
    _zip_dirent_apply_attributes(de, &attributes, (flags & ZIP_FL_FORCE_ZIP64) != 0, changed);

    if ((ret = _zip_dirent_write(za, de, flags)) < 0)
	return -1;

    if (is_zip64 != ret) {
	/* Zip64 mismatch between preliminary file header written before data and final file header written afterwards */
	zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	return -1;
    }

    if (zip_source_seek_write(za->src, offend, SEEK_SET) < 0) {
	_zip_error_set_from_source(&za->error, za->src);
	return -1;
    }

    if (de->bitflags & ZIP_GPBF_DATA_DESCRIPTOR) {
	if (write_data_descriptor(za, de, is_zip64) < 0) {
	    return -1;
	}
    }

    return 0;
}


static int
copy_data(zip_t *za, zip_uint64_t len) {
    DEFINE_BYTE_ARRAY(buf, BUFSIZE);
    size_t n;
    double total = (double)len;

    if (!byte_array_init(buf, BUFSIZE)) {
	zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return -1;
    }

    while (len > 0) {
	n = len > BUFSIZE ? BUFSIZE : len;
	if (_zip_read(za->src, buf, n, &za->error) < 0) {
	    byte_array_fini(buf);
	    return -1;
	}

	if (_zip_write(za, buf, n) < 0) {
	    byte_array_fini(buf);
	    return -1;
	}

	len -= n;

	if (_zip_progress_update(za->progress, (total - (double)len) / total) != 0) {
	    zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
	    return -1;
	}
    }

    byte_array_fini(buf);
    return 0;
}


static int
copy_source(zip_t *za, zip_source_t *src, zip_int64_t data_length) {
    DEFINE_BYTE_ARRAY(buf, BUFSIZE);
    zip_int64_t n, current;
    int ret;

    if (zip_source_open(src) < 0) {
	_zip_error_set_from_source(&za->error, src);
	return -1;
    }

    if (!byte_array_init(buf, BUFSIZE)) {
	zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return -1;
    }

    ret = 0;
    current = 0;
    while ((n = zip_source_read(src, buf, BUFSIZE)) > 0) {
	if (_zip_write(za, buf, (zip_uint64_t)n) < 0) {
	    ret = -1;
	    break;
	}
	if (n == BUFSIZE && za->progress && data_length > 0) {
	    current += n;
	    if (_zip_progress_update(za->progress, (double)current / (double)data_length) != 0) {
		zip_error_set(&za->error, ZIP_ER_CANCELLED, 0);
		ret = -1;
		break;
	    }
	}
    }

    if (n < 0) {
	_zip_error_set_from_source(&za->error, src);
	ret = -1;
    }

    byte_array_fini(buf);

    zip_source_close(src);

    return ret;
}

static int
write_cdir(zip_t *za, const zip_filelist_t *filelist, zip_uint64_t survivors) {
    zip_int64_t cd_start, end, size;

    if ((cd_start = zip_source_tell_write(za->src)) < 0) {
	return -1;
    }

    if ((size = _zip_cdir_write(za, filelist, survivors)) < 0) {
	return -1;
    }

    if ((end = zip_source_tell_write(za->src)) < 0) {
	return -1;
    }

    return 0;
}


int
_zip_changed(const zip_t *za, zip_uint64_t *survivorsp) {
    int changed;
    zip_uint64_t i, survivors;

    changed = 0;
    survivors = 0;

    if (za->comment_changed || za->ch_flags != za->flags) {
	changed = 1;
    }

    for (i = 0; i < za->nentry; i++) {
	if (ZIP_ENTRY_HAS_CHANGES(&za->entry[i])) {
	    changed = 1;
	}
	if (!za->entry[i].deleted) {
	    survivors++;
	}
    }

    if (survivorsp) {
	*survivorsp = survivors;
    }

    return changed;
}

static int
write_data_descriptor(zip_t *za, const zip_dirent_t *de, int is_zip64) {
    zip_buffer_t *buffer = _zip_buffer_new(NULL, MAX_DATA_DESCRIPTOR_LENGTH);
    int ret = 0;

    if (buffer == NULL) {
	zip_error_set(&za->error, ZIP_ER_MEMORY, 0);
	return -1;
    }

    _zip_buffer_put(buffer, DATADES_MAGIC, 4);
    _zip_buffer_put_32(buffer, de->crc);
    if (is_zip64) {
	_zip_buffer_put_64(buffer, de->comp_size);
	_zip_buffer_put_64(buffer, de->uncomp_size);
    }
    else {
	_zip_buffer_put_32(buffer, (zip_uint32_t)de->comp_size);
	_zip_buffer_put_32(buffer, (zip_uint32_t)de->uncomp_size);
    }

    if (!_zip_buffer_ok(buffer)) {
	zip_error_set(&za->error, ZIP_ER_INTERNAL, 0);
	ret = -1;
    }
    else {
	ret = _zip_write(za, _zip_buffer_data(buffer), _zip_buffer_offset(buffer));
    }

    _zip_buffer_free(buffer);

    return ret;
}
