/*
  fread.c -- test cases for reading from zip archives
  Copyright (C) 2004-2019 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 <stdio.h>
#include <stdlib.h>

#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);
#ifndef __clang_analyzer__ /* This test intentionally violates nullability. */
    fail += do_read(z, NULL, 0, WHEN_OPEN, ZIP_ER_INVAL, 0);
#endif
    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;
}
