//===----------------- Zip.cpp - Interface with zlib ----------------------===//
//
//                              JnJVM
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include <zlib.h>

#include "JavaArray.h"
#include "Reader.h"
#include "Zip.h"

using namespace jnjvm;

ZipArchive::ZipArchive(ArrayUInt8* bytes) {
  this->bytes = bytes;
  findOfscd();
  if (ofscd > -1)
    addFiles();
}

ZipFile* ZipArchive::getFile(const char* filename) {
  table_iterator End = filetable.end();
  table_iterator I = filetable.find(filename);
  return I != End ? I->second : 0;
}


#define END_CENTRAL_DIRECTORY_FILE_HEADER_SIZE 18
#define CENTRAL_DIRECTORY_FILE_HEADER_SIZE 42
#define LOCAL_FILE_HEADER_SIZE 26

#define C_FILENAME_LENGTH 24
#define C_UCSIZE 20
#define C_CSIZE 16
#define C_EXTRA_FIELD_LENGTH 26
#define C_FILE_COMMENT_LENGTH 28
#define C_ROLH 38
#define C_COMPRESSION_METHOD 6

#define L_FILENAME_LENGTH 22
#define L_EXTRA_FIELD_LENGTH 24

#define E_OFFSET_START_CENTRAL_DIRECTORY 12
#define HDR_ENDCENTRAL "PK\005\006"
#define HDR_CENTRAL "PK\001\002"
#define HDR_LOCAL "PK\003\004"
#define PATH_SEPARATOR '/'
#define ZIP_STORE 0
#define ZIP_DEFLATE 8
#define DEF_WBITS 15

static uint32 readEndianDep4(Reader& reader) {
  uint8 one = reader.readU1();
  uint8 two = reader.readU1();
  uint8 three = reader.readU1();
  uint8 four = reader.readU1();
  return (one + (two << 8) + (three << 16) + (four << 24));
}

static uint16 readEndianDep2(Reader& reader) {
  uint8 one = reader.readU1();
  uint8 two = reader.readU1();
  return (one + (two << 8));
}

void ZipArchive::findOfscd() {
  sint32 curOffs = 0;
  sint32 minOffs = 0;
  sint32 st = END_CENTRAL_DIRECTORY_FILE_HEADER_SIZE + 4;
  
  Reader reader(bytes);
  curOffs = reader.max;
  if (curOffs >= (65535 + END_CENTRAL_DIRECTORY_FILE_HEADER_SIZE + 4)) {
    minOffs = curOffs - (65535 + END_CENTRAL_DIRECTORY_FILE_HEADER_SIZE + 4);
  } else {
    minOffs = 0;
  }

  while (curOffs > minOffs) {
    sint32 searchPos = 0;
    if (curOffs >= (1024 - st)) {
      curOffs = curOffs - (1024 - st);
    } else {
      curOffs = 0;
    }
    reader.cursor += curOffs;

    sint32 diff = reader.max - reader.cursor;
    sint32 temp = reader.cursor;
    if (diff > 1024) {
      searchPos = 1024;
      reader.cursor += 1024;
    } else {
      searchPos = diff;
      reader.cursor = reader.max;
    }

    if (searchPos >= st) {
      sint32 searchPtr = temp + (searchPos - st);
      while (searchPtr > temp) {
        if (reader.bytes->elements[searchPtr] == 'P' && 
          !(memcmp(&(reader.bytes->elements[searchPtr]), HDR_ENDCENTRAL, 4))) {
          sint32 offset = searchPtr + 4 + E_OFFSET_START_CENTRAL_DIRECTORY;
          reader.cursor = offset;
          this->ofscd = readEndianDep4(reader);
          return;
        }
      }
    }
  }
  this->ofscd = -1;
}

void ZipArchive::addFiles() {
  sint32 temp = ofscd;
  
  Reader reader(bytes);
  reader.cursor = temp;

  while (true) {
    if (memcmp(&(reader.bytes->elements[temp]), HDR_CENTRAL, 4)) return;
    ZipFile* ptr = new ZipFile();
    reader.cursor = temp + 4 + C_COMPRESSION_METHOD;
    ptr->compressionMethod = readEndianDep2(reader);
    
    reader.cursor = temp + 4 + C_CSIZE;
    
    ptr->csize = readEndianDep4(reader);
    ptr->ucsize = readEndianDep4(reader);
    ptr->filenameLength = readEndianDep2(reader);
    ptr->extraFieldLength = readEndianDep2(reader);
    ptr->fileCommentLength = readEndianDep2(reader);

    reader.cursor = temp + 4 + C_ROLH;
    ptr->rolh = readEndianDep4(reader);

    temp = temp + 4 + CENTRAL_DIRECTORY_FILE_HEADER_SIZE;

    if ((ptr->filenameLength > 1024) || 
        (reader.max - temp) < ptr->filenameLength)
      return;

    ptr->filename = (char*)malloc(ptr->filenameLength + 1);
    memcpy(ptr->filename, &(reader.bytes->elements[temp]), ptr->filenameLength);
    ptr->filename[ptr->filenameLength] = 0;

    if (ptr->filename[ptr->filenameLength - 1] != PATH_SEPARATOR) {
      filetable.insert(std::make_pair(ptr->filename, ptr));
    }

    temp = temp + ptr->filenameLength + ptr->extraFieldLength + 
      ptr->fileCommentLength;
  }
}

sint32 ZipArchive::readFile(ArrayUInt8* array, const ZipFile* file) {
  uint32 bytesLeft = 0;
  uint32 filenameLength = 0;
  uint32 extraFieldLength = 0;
  char* ptr = (char*)array->elements;
  uint32 temp = 0;

  Reader reader(bytes);
  reader.cursor = file->rolh;
  
  if (!(memcmp(&(reader.bytes->elements[file->rolh]), HDR_LOCAL, 4))) {
    reader.cursor += 4;
    temp = reader.cursor;
    reader.cursor += L_FILENAME_LENGTH;
    filenameLength = readEndianDep2(reader);
    extraFieldLength = readEndianDep2(reader);

    reader.cursor = 
      temp + extraFieldLength + filenameLength + LOCAL_FILE_HEADER_SIZE;

    if (file->compressionMethod == ZIP_STORE) {
      memcpy(ptr, &(reader.bytes->elements[reader.cursor]), file->ucsize);
    } else if (file->compressionMethod == ZIP_DEFLATE) {
      z_stream stre;
      sint32 err = 0;
      
      bytesLeft = file->csize;
      stre.next_out = (Bytef*)ptr;
      stre.avail_out = file->ucsize;
      stre.zalloc = 0;
      stre.zfree = 0;

      err = inflateInit2_(&stre, - DEF_WBITS, zlib_version, sizeof(z_stream));
  
      if (err != Z_OK) {
        return 0;
      }

      while (bytesLeft) {
        uint32 size = 0;
        stre.next_in = &(reader.bytes->elements[reader.cursor]);
        if (bytesLeft > 1024) size = 1024;
        else size = bytesLeft;

        uint32 diff = reader.max - reader.cursor;
        if (diff < size) {
          stre.avail_in = diff;
          reader.cursor = reader.max;
        } else {
          stre.avail_in = size;
          reader.cursor += size;
        }

        if (bytesLeft > size) {
          err = inflate(&stre, Z_PARTIAL_FLUSH);
        } else {
          err = inflate(&stre, Z_FINISH);
        }

        bytesLeft = bytesLeft - size;
      }

      inflateEnd(&stre);

      if ((err != Z_STREAM_END) && 
          (bytesLeft || err != Z_BUF_ERROR || stre.avail_out)) {
        return 0;
      } else {
        return 1;
      }
    } else {
      return 0;
    }
  } else {
    return 0;
  }
  return 0;
}
