/*
  fread.c -- test cases for reading from zip archives
  Copyright (C) 2004-2016 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 *prg;
#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;

    prg = argv[0];

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

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

    
    if (argc-optind != 1) {
        fprintf(stderr, USAGE, prg);
        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", prg, 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", prg, 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", prg, 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", prg, 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", prg, 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", prg, 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", prg, 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",
	       prg, 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", prg, name);

    return 0;
}
