/*
 * Copyright 2003-2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */
#include <sys/types.h>

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdarg.h>
#include <errno.h>

#include <limits.h>
#include <time.h>

#if defined(unix) && !defined(PRODUCT)
#include "pthread.h"
#define THREAD_SELF ((int)pthread_self())
#endif

#include "defines.h"
#include "bytes.h"
#include "utils.h"
#include "coding.h"
#include "bands.h"

#include "constants.h"

#include "zip.h"

#include "unpack.h"


int main(int argc, char **argv) {
    return unpacker::run(argc, argv);
}

// Single-threaded, implementation, not reentrant.
// Includes a weak error check against MT access.
#ifndef THREAD_SELF
#define THREAD_SELF (0)
#endif
NOT_PRODUCT(static int uThread = -1;)

unpacker* unpacker::non_mt_current = null;
unpacker* unpacker::current() {
  assert(uThread == THREAD_SELF);
  return non_mt_current;
}
static void set_current_unpacker(unpacker* u) {
  unpacker::non_mt_current = u;
  assert(((uThread = (u == null) ? -1 : THREAD_SELF),
          true));
}

// Callback for fetching data, Unix style.
static jlong read_input_via_stdio(unpacker* u,
                                  void* buf, jlong minlen, jlong maxlen) {
  assert(minlen <= maxlen);  // don't talk nonsense
  jlong numread = 0;
  char* bufptr = (char*) buf;
  while (numread < minlen) {
    // read available input, up to buf.length or maxlen
    int readlen = (1<<16);
    if (readlen > (maxlen - numread))
      readlen = (int)(maxlen - numread);
    int nr = 0;
    if (u->infileptr != null) {
      nr = fread(bufptr, 1, readlen, u->infileptr);
    } else {
#ifndef WIN32
      // we prefer unbuffered inputs
      nr = read(u->infileno, bufptr, readlen);
#else
      nr = fread(bufptr, 1, readlen, stdin);
#endif
    }
    if (nr <= 0) {
      if (errno != EINTR)
        break;
      nr = 0;
    }
    numread += nr;
    bufptr += nr;
    assert(numread <= maxlen);
  }
  //fprintf(u->errstrm, "readInputFn(%d,%d) => %d\n",
  //        (int)minlen, (int)maxlen, (int)numread);
  return numread;
}

enum { EOF_MAGIC = 0, BAD_MAGIC = -1 };
static int read_magic(unpacker* u, char peek[], int peeklen) {
  assert(peeklen == 4);  // magic numbers are always 4 bytes
  jlong nr = (u->read_input_fn)(u, peek, peeklen, peeklen);
  if (nr != peeklen) {
    return (nr == 0) ? EOF_MAGIC : BAD_MAGIC;
  }
  int magic = 0;
  for (int i = 0; i < peeklen; i++) {
    magic <<= 8;
    magic += peek[i] & 0xFF;
  }
  return magic;
}

static void setup_gzin(unpacker* u) {
  gunzip* gzin = NEW(gunzip, 1);
  gzin->init(u);
}

static const char* nbasename(const char* progname) {
  const char* slash = strrchr(progname, '/');
  if (slash != null)  progname = ++slash;
  return progname;
}

static const char* usage_lines[] = {
  "Usage:  %s [-opt... | --option=value]... x.pack[.gz] y.jar\n",
    "\n",
    "Unpacking Options\n",
    "  -H{h}, --deflate-hint={h}     override transmitted deflate hint: true, false, or keep (default)\n",
    "  -r, --remove-pack-file        remove input file after unpacking\n",
    "  -v, --verbose                 increase program verbosity\n",
    "  -q, --quiet                   set verbosity to lowest level\n",
    "  -l{F}, --log-file={F}         output to the given log file, or '-' for standard output (default)\n",
    "  -?, -h, --help                print this message\n",
    "  -V, --version                 print program version\n",
    "  -J{X}                         Java VM argument (ignored)\n",
    null
};

static void usage(unpacker* u, const char* progname, bool full = false) {
  // WinMain does not set argv[0] to the progrname
  progname = (progname != null) ? nbasename(progname) : "unpack200";
  for (int i = 0; usage_lines[i] != null; i++) {
    fprintf(u->errstrm, usage_lines[i], progname);
    if (!full) {
      fprintf(u->errstrm,
              "(For more information, run %s --help .)\n", progname);
      break;
    }
  }
}

// argument parsing
static char** init_args(int argc, char** argv, int &envargc) {
  const char* env = getenv("UNPACK200_FLAGS");
  ptrlist envargs;
  envargs.init();
  if (env != null) {
    char* buf = (char*) strdup(env);
    const char* delim = "\n\t ";
    for (char* p = strtok(buf, delim); p != null; p = strtok(null, delim)) {
      envargs.add(p);
    }
  }
  // allocate extra margin at both head and tail
  char** argp = NEW(char*, envargs.length()+argc+1);
  char** argp0 = argp;
  int i;
  for (i = 0; i < envargs.length(); i++) {
    *argp++ = (char*) envargs.get(i);
  }
  for (i = 1; i < argc; i++) {
    // note: skip argv[0] (program name)
    *argp++ = (char*) strdup(argv[i]);  // make a scratch copy
  }
  *argp = null; // sentinel
  envargc = envargs.length();  // report this count to next_arg
  envargs.free();
  return argp0;
}

static int strpcmp(const char* str, const char* pfx) {
  return strncmp(str, pfx, strlen(pfx));
}

static const char flag_opts[] = "vqrVh?";
static const char string_opts[] = "HlJ";

static int next_arg(char** &argp) {
  char* arg = *argp;
  if (arg == null || arg[0] != '-') { // end of option list
    return 0;
  }
  //printf("opt: %s\n", arg);
  char ach = arg[1];
  if (ach == '\0') {
    // ++argp;  // do not pop this arg
    return 0;  // bare "-" is stdin/stdout
  } else if (arg[1] == '-') {  // --foo option
    static const char* keys[] = {
      "Hdeflate-hint=",
      "vverbose",
      "qquiet",
      "rremove-pack-file",
      "llog-file=",
      "Vversion",
      "hhelp",
      null };
    if (arg[2] == '\0') {  // end of option list
      ++argp;  // pop the "--"
      return 0;
    }
    for (int i = 0; keys[i] != null; i++) {
      const char* key = keys[i];
      char kch = *key++;
      if (strchr(key, '=') == null) {
        if (!strcmp(arg+2, key)) {
          ++argp;  // pop option arg
          return kch;
        }
      } else {
        if (!strpcmp(arg+2, key)) {
          *argp += 2 + strlen(key);  // remove "--"+key from arg
          return kch;
        }
      }
    }
  } else if (strchr(flag_opts, ach) != null) {  // plain option
    if (arg[2] == '\0') {
      ++argp;
    } else {
      // in-place edit of "-vxyz" to "-xyz"
      arg += 1;  // skip original '-'
      arg[0] = '-';
      *argp = arg;
    }
    //printf("  key => %c\n", ach);
    return ach;
  } else if (strchr(string_opts, ach) != null) {  // argument-bearing option
    if (arg[2] == '\0') {
      if (argp[1] == null)  return -1;  // no next arg
      ++argp;  // leave the argument in place
    } else {
      // in-place edit of "-Hxyz" to "xyz"
      arg += 2;  // skip original '-H'
      *argp = arg;
    }
    //printf("  key => %c\n", ach);
    return ach;
  }
  return -1;  // bad argument
}

static const char sccsver[] = "1.30, 07/05/05";

// Usage:  unpackage input.pack output.jar
int unpacker::run(int argc, char **argv) {
  unpacker u;
  u.init(read_input_via_stdio);
  set_current_unpacker(&u);

  jar jarout;
  jarout.init(&u);

  int envargc = 0;
  char** argbuf = init_args(argc, argv, envargc);
  char** arg0 = argbuf+envargc;
  char** argp = argbuf;
  int ach;

  int verbose = 0;
  char* logfile = null;

  for (;;) {
    const char* arg = (*argp == null)? "": u.saveStr(*argp);
    bool isenvarg = (argp < arg0);
    int ach = next_arg(argp);
    bool hasoptarg = (ach != 0 && strchr(string_opts, ach) != null);
    if (ach == 0 && argp >= arg0)  break;
    if (isenvarg && argp == arg0 && hasoptarg)  ach = 0;  // don't pull from cmdline
    switch (ach) {
    case 'H':  u.set_option(UNPACK_DEFLATE_HINT,*argp++); break;
    case 'v':  ++verbose; break;
    case 'q':  verbose = 0; break;
    case 'r':  u.set_option(UNPACK_REMOVE_PACKFILE,"1"); break;
    case 'l':  logfile = *argp++; break;
    case 'J':  argp += 1; break;  // skip ignored -Jxxx parameter

    case 'V':
      fprintf(u.errstrm, "%s version %s\n", nbasename(argv[0]), sccsver);
      exit(0);

    case 'h':
    case '?':
      usage(&u, argv[0], true);
      exit(1);

    default:
      const char* inenv = isenvarg? " in ${UNPACK200_FLAGS}": "";
      if (hasoptarg)
        fprintf(u.errstrm, "Missing option string%s: %s\n", inenv, arg);
      else
        fprintf(u.errstrm, "Unrecognized argument%s: %s\n", inenv, arg);
      usage(&u, argv[0]);
      exit(2);
    }
  }

  if (verbose != 0) {
    u.set_option(DEBUG_VERBOSE, u.saveIntStr(verbose));
  }
  if (logfile != null) {
    u.set_option(UNPACK_LOG_FILE, logfile);
  }

  u.redirect_stdio();

  const char* source_file      = *argp++;
  const char* destination_file = *argp++;

  if (source_file == null || destination_file == null || *argp != null) {
    usage(&u, argv[0]);
    exit(2);
  }

  if (verbose != 0) {
    fprintf(u.errstrm,
            "Unpacking from %s to %s\n", source_file, destination_file);
  }
  bool& remove_source = u.remove_packfile;

  if (strcmp(source_file, "-") == 0) {
    remove_source = false;
    u.infileno = fileno(stdin);
  } else {
    u.infileptr = fopen(source_file, "rb");
    if (u.infileptr == null) {
       fprintf(u.errstrm,
               "Error: Could not open input file: %s\n", source_file);
       exit(3); // Called only from the native standalone unpacker
    }
  }

  if (strcmp(destination_file, "-") == 0) {
    jarout.jarfp = stdout;
    if (u.errstrm == stdout) // do not mix output
      u.set_option(UNPACK_LOG_FILE, LOGFILE_STDERR);
  } else {
    jarout.openJarFile(destination_file);
    assert(jarout.jarfp != null);
  }

  if (verbose != 0)
    u.dump_options();

  char peek[4];
  int magic;

  // check for GZIP input
  magic = read_magic(&u, peek, sizeof(peek));
  if ((magic & GZIP_MAGIC_MASK) == GZIP_MAGIC) {
    // Oops; must slap an input filter on this data.
    setup_gzin(&u);
    u.gzin->start(magic);
    if (!u.aborting()) {
      u.start();
    }
  } else {
    u.start(peek, sizeof(peek));
  }

  // Note:  The checks to u.aborting() are necessary to gracefully
  // terminate processing when the first segment throws an error.

  for (;;) {
    if (u.aborting())  break;

    // Each trip through this loop unpacks one segment
    // and then resets the unpacker.
    for (unpacker::file* filep; (filep = u.get_next_file()) != null; ) {
      if (u.aborting())  break;
      u.write_file_to_jar(filep);
    }
    if (u.aborting())  break;

    // Peek ahead for more data.
    magic = read_magic(&u, peek, sizeof(peek));
    if (magic != JAVA_PACKAGE_MAGIC) {
      if (magic != EOF_MAGIC)
        u.abort("garbage after end of pack archive");
      break;   // all done
    }

    // Release all storage from parsing the old segment.
    u.reset();

    // Restart, beginning with the peek-ahead.
    u.start(peek, sizeof(peek));
  }



  int status = 0;
  if (u.aborting()) {
    fprintf(u.errstrm, "Error: %s\n", u.get_abort_message());
    status = 1;
  }

  if (u.infileptr != null) {
    fclose(u.infileptr);
    u.infileptr = null;
  }

  if (!u.aborting() && remove_source)
    remove(source_file);

  if (verbose != 0) {
    fprintf(u.errstrm, "unpacker completed with status=%d\n", status);
  }

  u.finish();

  u.free();  // tidy up malloc blocks
  set_current_unpacker(null);  // clean up global pointer

  return status;
}
