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