#ifndef LIBRARIES_ZIP_H
#define LIBRARIES_ZIP_H

/* zipconf */

#define LIBZIP_VERSION "0.11.2"
#define LIBZIP_VERSION_MAJOR 0
#define LIBZIP_VERSION_MINOR 11
#define LIBZIP_VERSION_MICRO 2

#ifndef EXEC_TYPES_H
#include <exec/types.h>
#endif

#include <stdint.h>
#include <time.h>
#include <stdio.h>

typedef int8_t zip_int8_t;
#define ZIP_INT8_MIN INT8_MIN
#define ZIP_INT8_MAX INT8_MAX

typedef uint8_t zip_uint8_t;
#define ZIP_UINT8_MAX UINT8_MAX

typedef int16_t zip_int16_t;
#define ZIP_INT16_MIN INT16_MIN
#define ZIP_INT16_MAX INT16_MAX

typedef uint16_t zip_uint16_t;
#define ZIP_UINT16_MAX UINT16_MAX

typedef int32_t zip_int32_t;
#define ZIP_INT32_MIN INT32_MIN
#define ZIP_INT32_MAX INT32_MAX

typedef uint32_t zip_uint32_t;
#define ZIP_UINT32_MAX UINT32_MAX

typedef int64_t zip_int64_t;
#define ZIP_INT64_MIN INT64_MIN
#define ZIP_INT64_MAX INT64_MAX

typedef uint64_t zip_uint64_t;
#define ZIP_UINT64_MAX UINT64_MAX

/* flags for zip_open */

#define ZIP_CREATE    1
#define ZIP_EXCL      2
#define ZIP_CHECKCONS 4
#define ZIP_TRUNCATE  8

/* flags for zip_name_locate, zip_fopen, zip_stat, ... */

#define ZIP_FL_NOCASE        1u /* ignore case on name lookup */
#define ZIP_FL_NODIR         2u /* ignore directory component */
#define ZIP_FL_COMPRESSED    4u /* read compressed data */
#define ZIP_FL_UNCHANGED     8u /* use original data, ignoring changes */
#define ZIP_FL_RECOMPRESS   16u /* force recompression of data */
#define ZIP_FL_ENCRYPTED    32u /* read encrypted data (implies ZIP_FL_COMPRESSED) */
#define ZIP_FL_ENC_GUESS     0u /* guess string encoding (is default) */
#define ZIP_FL_ENC_RAW      64u /* get unmodified string */
#define ZIP_FL_ENC_STRICT  128u /* follow specification strictly */
#define ZIP_FL_LOCAL	   256u /* in local header */
#define ZIP_FL_CENTRAL	   512u /* in central directory */
/*                        1024u    reserved for internal use */
#define ZIP_FL_ENC_UTF_8  2048u /* string is UTF-8 encoded */
#define ZIP_FL_ENC_CP437  4096u /* string is CP437 encoded */
#define ZIP_FL_OVERWRITE  8192u /* zip_file_add: if file with name exists, overwrite (replace) it */

/* archive global flags flags */

#define ZIP_AFL_TORRENT 1u /* torrent zipped */
#define ZIP_AFL_RDONLY  2u /* read only -- cannot be cleared */

/* create a new extra field */

#define ZIP_EXTRA_FIELD_ALL ZIP_UINT16_MAX
#define ZIP_EXTRA_FIELD_NEW ZIP_UINT16_MAX

/* flags for compression and encryption sources */

#define ZIP_CODEC_DECODE 0 /* decompress/decrypt (encode flag not set) */
#define ZIP_CODEC_ENCODE 1 /* compress/encrypt */

/* libzip error codes */

#define ZIP_ER_OK           0 /* N No error */
#define ZIP_ER_MULTIDISK    1 /* N Multi-disk zip archives not supported */
#define ZIP_ER_RENAME       2 /* S Renaming temporary file failed */
#define ZIP_ER_CLOSE        3 /* S Closing zip archive failed */
#define ZIP_ER_SEEK         4 /* S Seek error */
#define ZIP_ER_READ         5 /* S Read error */
#define ZIP_ER_WRITE        6 /* S Write error */
#define ZIP_ER_CRC          7 /* N CRC error */
#define ZIP_ER_ZIPCLOSED    8 /* N Containing zip archive was closed */
#define ZIP_ER_NOENT        9 /* N No such file */
#define ZIP_ER_EXISTS      10 /* N File already exists */
#define ZIP_ER_OPEN        11 /* S Can't open file */
#define ZIP_ER_TMPOPEN     12 /* S Failure to create temporary file */
#define ZIP_ER_ZLIB        13 /* Z Zlib error */
#define ZIP_ER_MEMORY      14 /* N Malloc failure */
#define ZIP_ER_CHANGED     15 /* N Entry has been changed */
#define ZIP_ER_COMPNOTSUPP 16 /* N Compression method not supported */
#define ZIP_ER_EOF         17 /* N Premature EOF */
#define ZIP_ER_INVAL       18 /* N Invalid argument */
#define ZIP_ER_NOZIP       19 /* N Not a zip archive */
#define ZIP_ER_INTERNAL    20 /* N Internal error */
#define ZIP_ER_INCONS      21 /* N Zip archive inconsistent */
#define ZIP_ER_REMOVE      22 /* S Can't remove file */
#define ZIP_ER_DELETED     23 /* N Entry has been deleted */
#define ZIP_ER_ENCRNOTSUPP 24 /* N Encryption method not supported */
#define ZIP_ER_RDONLY      25 /* N Read-only archive */ 
#define ZIP_ER_NOPASSWD    26 /* N No password provided */
#define ZIP_ER_WRONGPASSWD 27 /* N Wrong password provided */

/* type of system error value */

#define ZIP_ET_NONE	0 /* sys_err unused */
#define ZIP_ET_SYS	1 /* sys_err is errno */
#define ZIP_ET_ZLIB	2 /* sys_err is zlib error code */

/* compression methods */

#define ZIP_CM_DEFAULT	      -1 /* better of deflate or store */
#define ZIP_CM_STORE	       0 /* stored (uncompressed) */
#define ZIP_CM_SHRINK	       1 /* shrunk */
#define ZIP_CM_REDUCE_1	       2 /* reduced with factor 1 */
#define ZIP_CM_REDUCE_2	       3 /* reduced with factor 2 */
#define ZIP_CM_REDUCE_3	       4 /* reduced with factor 3 */
#define ZIP_CM_REDUCE_4	       5 /* reduced with factor 4 */
#define ZIP_CM_IMPLODE	       6 /* imploded */
/* 7 - Reserved for Tokenizing compression algorithm */
#define ZIP_CM_DEFLATE	       8 /* deflated */
#define ZIP_CM_DEFLATE64       9 /* deflate64 */
#define ZIP_CM_PKWARE_IMPLODE 10 /* PKWARE imploding */
/* 11 - Reserved by PKWARE */
#define ZIP_CM_BZIP2          12 /* compressed using BZIP2 algorithm */
/* 13 - Reserved by PKWARE */
#define ZIP_CM_LZMA           14 /* LZMA (EFS) */
/* 15-17 - Reserved by PKWARE */
#define ZIP_CM_TERSE	      18 /* compressed using IBM TERSE (new) */
#define ZIP_CM_LZ77           19 /* IBM LZ77 z Architecture (PFS) */
#define ZIP_CM_WAVPACK	      97 /* WavPack compressed data */
#define ZIP_CM_PPMD           98 /* PPMd version I, Rev 1 */

/* encryption methods */

#define ZIP_EM_NONE	       0 /* not encrypted */
#define ZIP_EM_TRAD_PKWARE 1 /* traditional PKWARE encryption */
#if 0 /* Strong Encryption Header not parsed yet */
#define ZIP_EM_DES      0x6601 /* strong encryption: DES */
#define ZIP_EM_RC2_OLD  0x6602 /* strong encryption: RC2, version < 5.2 */
#define ZIP_EM_3DES_168 0x6603
#define ZIP_EM_3DES_112 0x6609
#define ZIP_EM_AES_128  0x660e
#define ZIP_EM_AES_192  0x660f
#define ZIP_EM_AES_256  0x6610
#define ZIP_EM_RC2      0x6702 /* strong encryption: RC2, version >= 5.2 */
#define ZIP_EM_RC4      0x6801
#endif
#define ZIP_EM_UNKNOWN  0xffff /* unknown algorithm */

#define ZIP_OPSYS_DOS           0x00u
#define ZIP_OPSYS_AMIGA         0x01u
#define ZIP_OPSYS_OPENVMS       0x02u
#define ZIP_OPSYS_UNIX          0x03u
#define ZIP_OPSYS_VM_CMS        0x04u
#define ZIP_OPSYS_ATARI_ST      0x05u
#define ZIP_OPSYS_OS_2          0x06u
#define ZIP_OPSYS_MACINTOSH     0x07u
#define ZIP_OPSYS_Z_SYSTEM      0x08u
#define ZIP_OPSYS_CPM           0x09u
#define ZIP_OPSYS_WINDOWS_NTFS  0x0au
#define ZIP_OPSYS_MVS           0x0bu
#define ZIP_OPSYS_VSE           0x0cu
#define ZIP_OPSYS_ACORN_RISC    0x0du
#define ZIP_OPSYS_VFAT          0x0eu
#define ZIP_OPSYS_ALTERNATE_MVS 0x0fu
#define ZIP_OPSYS_BEOS          0x10u
#define ZIP_OPSYS_TANDEM        0x11u
#define ZIP_OPSYS_OS_400        0x12u
#define ZIP_OPSYS_OS_X          0x13u

#define ZIP_OPSYS_DEFAULT ZIP_OPSYS_UNIX

enum zip_source_cmd {
    ZIP_SOURCE_OPEN,  /* prepare for reading */
    ZIP_SOURCE_READ,  /* read data */
    ZIP_SOURCE_CLOSE, /* reading is done */
    ZIP_SOURCE_STAT,  /* get meta information */
    ZIP_SOURCE_ERROR, /* get error information */
    ZIP_SOURCE_FREE   /* cleanup and free resources */
};

#define ZIP_SOURCE_ERR_LOWER -2

#define ZIP_STAT_NAME              0x0001u
#define ZIP_STAT_INDEX             0x0002u
#define ZIP_STAT_SIZE              0x0004u
#define ZIP_STAT_COMP_SIZE         0x0008u
#define ZIP_STAT_MTIME             0x0010u
#define ZIP_STAT_CRC               0x0020u
#define ZIP_STAT_COMP_METHOD       0x0040u
#define ZIP_STAT_ENCRYPTION_METHOD 0x0080u
#define ZIP_STAT_FLAGS             0x0100u

struct zip_stat {
    zip_uint64_t valid;             /* which fields have valid values */
    CONST_STRPTR name;              /* name of the file */
    zip_uint64_t index;             /* index within archive */
    zip_uint64_t size;              /* size of file (uncompressed) */
    zip_uint64_t comp_size;         /* size of file (compressed) */
    time_t mtime;                   /* modification time */
    zip_uint32_t crc;               /* crc of file data */
    zip_uint16_t comp_method;       /* compression method used */
    zip_uint16_t encryption_method; /* encryption method used */
    zip_uint32_t flags;             /* reserved for future use */
};

struct zip;
struct zip_file;
struct zip_source;

typedef zip_uint32_t zip_flags_t;

typedef zip_int64_t (*zip_source_callback)(void *, void *, zip_uint64_t, enum zip_source_cmd);

#endif /* LIBRARIES_ZIP_H */

