/*
  fread.c -- test cases for reading from zip archives
  Copyright (C) 2004-2018 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 "config.h"

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#ifndef HAVE_GETOPT
#include "getopt.h"
#endif

#include "zip.h"

enum when { WHEN_NEVER, WHEN_OPEN, WHEN_READ, WHEN_CLOSE };

const char *when_name[] = {"no", "zip_fopen", "zip_fread", "zip_fclose"};

static int do_read(zip_t *z, const char *name, zip_flags_t flags, enum when when_ex, int ze_ex, int se_ex);

int verbose;

const char *progname;
#define USAGE "usage: %s [-v] archive\n"

int
main(int argc, char *argv[]) {
    int fail, ze;
    int c;
    zip_t *z;
    zip_source_t *zs;
    char *archive;
    zip_int64_t idx;

    verbose = 0;
    fail = 0;

    progname = argv[0];

    while ((c = getopt(argc, argv, "v")) != -1) {
	switch (c) {
	case 'v':
	    verbose = 1;
	    break;

	default:
	    fprintf(stderr, USAGE, progname);
	    return 1;
	}
    }


    if (argc - optind != 1) {
	fprintf(stderr, USAGE, progname);
	return 1;
    }

    archive = argv[optind];

    if ((z = zip_open(archive, 0, &ze)) == NULL) {
	zip_error_t error;
	zip_error_init_with_code(&error, ze);
	fprintf(stderr, "%s: can't open zip archive '%s': %s\n", progname, archive, zip_error_strerror(&error));
	zip_error_fini(&error);
	return 1;
    }

    fail += do_read(z, "storedok", 0, WHEN_NEVER, 0, 0);
    fail += do_read(z, "deflateok", 0, WHEN_NEVER, 0, 0);
    fail += do_read(z, "storedcrcerror", 0, WHEN_READ, ZIP_ER_CRC, 0);
    fail += do_read(z, "deflatecrcerror", 0, WHEN_READ, ZIP_ER_CRC, 0);
    fail += do_read(z, "deflatezliberror", 0, WHEN_READ, ZIP_ER_ZLIB, -3);
    fail += do_read(z, NULL, 0, WHEN_OPEN, ZIP_ER_INVAL, 0);
    fail += do_read(z, "nosuchfile", 0, WHEN_OPEN, ZIP_ER_NOENT, 0);
    fail += do_read(z, "deflatezliberror", ZIP_FL_COMPRESSED, WHEN_NEVER, 0, 0);
    fail += do_read(z, "deflatecrcerror", ZIP_FL_COMPRESSED, WHEN_NEVER, 0, 0);
    fail += do_read(z, "storedcrcerror", ZIP_FL_COMPRESSED, WHEN_READ, ZIP_ER_CRC, 0);
    fail += do_read(z, "storedok", ZIP_FL_COMPRESSED, WHEN_NEVER, 0, 0);

    fail += do_read(z, "cryptok", 0, WHEN_OPEN, ZIP_ER_NOPASSWD, 0);
    zip_set_default_password(z, "crypt");
    fail += do_read(z, "cryptok", 0, WHEN_NEVER, 0, 0);
    zip_set_default_password(z, "wrong");
    fail += do_read(z, "cryptok", 0, WHEN_OPEN, ZIP_ER_WRONGPASSWD, 0);
    zip_set_default_password(z, NULL);

    zs = zip_source_buffer(z, "asdf", 4, 0);
    if ((idx = zip_name_locate(z, "storedok", 0)) < 0) {
	fprintf(stderr, "%s: can't locate 'storedok' in zip archive '%s': %s\n", progname, archive, zip_strerror(z));
	fail++;
    }
    else {
	if (zip_replace(z, (zip_uint64_t)idx, zs) < 0) {
	    fprintf(stderr, "%s: can't replace 'storedok' in zip archive '%s': %s\n", progname, archive, zip_strerror(z));
	    fail++;
	}
	else {
	    fail += do_read(z, "storedok", 0, WHEN_OPEN, ZIP_ER_CHANGED, 0);
	    fail += do_read(z, "storedok", ZIP_FL_UNCHANGED, WHEN_NEVER, 0, 0);
	}
    }
    if ((idx = zip_name_locate(z, "storedok", 0)) < 0) {
	fprintf(stderr, "%s: can't locate 'storedok' in zip archive '%s': %s\n", progname, archive, zip_strerror(z));
	fail++;
    }
    else {
	if (zip_delete(z, (zip_uint64_t)idx) < 0) {
	    fprintf(stderr, "%s: can't replace 'storedok' in zip archive '%s': %s\n", progname, archive, zip_strerror(z));
	    fail++;
	}
	else {
	    fail += do_read(z, "storedok", 0, WHEN_OPEN, ZIP_ER_NOENT, 0);
	    fail += do_read(z, "storedok", ZIP_FL_UNCHANGED, WHEN_NEVER, 0, 0);
	}
    }
    zs = zip_source_buffer(z, "asdf", 4, 0);
    if (zip_file_add(z, "new_file", zs, 0) < 0) {
	fprintf(stderr, "%s: can't add file to zip archive '%s': %s\n", progname, archive, zip_strerror(z));
	fail++;
    }
    else {
	fail += do_read(z, "new_file", 0, WHEN_OPEN, ZIP_ER_CHANGED, 0);
    }

    zip_unchange_all(z);
    if (zip_close(z) == -1) {
	fprintf(stderr, "%s: can't close zip archive '%s': %s\n", progname, archive, zip_strerror(z));
	return 1;
    }

    exit(fail ? 1 : 0);
}


static int
do_read(zip_t *z, const char *name, zip_flags_t flags, enum when when_ex, int ze_ex, int se_ex) {
    zip_file_t *zf;
    enum when when_got;
    zip_error_t error_got, error_ex;
    zip_error_t *zf_error;
    int err;
    char b[8192];
    zip_int64_t n;

    when_got = WHEN_NEVER;
    zip_error_init(&error_got);
    zip_error_init(&error_ex);
    zip_error_set(&error_ex, ze_ex, se_ex);

    if ((zf = zip_fopen(z, name, flags)) == NULL) {
	when_got = WHEN_OPEN;
	zf_error = zip_get_error(z);
	zip_error_set(&error_got, zip_error_code_zip(zf_error), zip_error_code_system(zf_error));
    }
    else {
	while ((n = zip_fread(zf, b, sizeof(b))) > 0)
	    ;
	if (n < 0) {
	    when_got = WHEN_READ;
	    zf_error = zip_file_get_error(zf);
	    zip_error_set(&error_got, zip_error_code_zip(zf_error), zip_error_code_system(zf_error));
	}
	err = zip_fclose(zf);
	if (when_got == WHEN_NEVER && err != 0) {
	    when_got = WHEN_CLOSE;
	    zip_error_init_with_code(&error_got, err);
	}
    }

    if (when_got != when_ex || zip_error_code_zip(&error_got) != zip_error_code_zip(&error_ex) || zip_error_code_system(&error_got) != zip_error_code_system(&error_ex)) {
	printf("%s: %s: got %s error (%s), expected %s error (%s)\n", progname, name, when_name[when_got], zip_error_strerror(&error_got), when_name[when_ex], zip_error_strerror(&error_ex));
	zip_error_fini(&error_got);
	zip_error_fini(&error_ex);
	return 1;
    }
    else if (verbose)
	printf("%s: %s: passed\n", progname, name);

    return 0;
}
