/*
  zip_close.c -- close zip archive and update changes
  Copyright (C) 1999-2021 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, i, ZIP_FL_UNCHANGED, 0, 0, NULL, &za->error)) == 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_create(src_final, 0, &za->error)) == 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) {
    if (zip_source_tell_write(za->src) < 0) {
        return -1;
    }

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

    if (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;
}
