/* Copyright (C) 2004, 2005  Free Software Foundation

   This file is part of libgcj.

This software is copyrighted work licensed under the terms of the
Libgcj License.  Please consult the file "LIBGCJ_LICENSE" for
details.  */

package gnu.gcj.tools.gcj_dbtool;


import gnu.gcj.runtime.PersistentByteMap;
import java.io.*;
import java.nio.channels.*;
import java.util.*;
import java.util.jar.*;
import java.security.MessageDigest;

public class Main
{
  static private boolean verbose = false;

  public static void main (String[] s)
  {
    boolean fileListFromStdin = false;
    char filenameSeparator = ' ';

    insist (s.length >= 1);

    if (s[0].equals("-") ||
	s[0].equals("-0"))
      {
	if (s[0].equals("-0"))
	  filenameSeparator = (char)0;
	fileListFromStdin = true;
	String[] newArgs = new String[s.length - 1];
	System.arraycopy(s, 1, newArgs, 0, s.length - 1);
	s = newArgs;
      }

    if (s[0].equals("-v") || s[0].equals("--version"))
      {
	insist (s.length == 1);
	System.out.println("gcj-dbtool ("
			   + System.getProperty("java.vm.name")
			   + ") "
			   + System.getProperty("java.vm.version"));
	System.out.println();
	System.out.println("Copyright 2005 Free Software Foundation, Inc.");
	System.out.println("This is free software; see the source for copying conditions.  There is NO");
	System.out.println("warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.");
	return;
      }
    if (s[0].equals("--help"))
      {
	usage(System.out);
	return;
      }

    if (s[0].equals("-n"))
      {
	// Create a new database.
	insist (s.length >= 2 && s.length <= 3);

	int capacity = 32749;

	if (s.length == 3)
	  {	    
	    capacity = Integer.parseInt(s[2]);

	    if (capacity <= 2)
	      {
		usage(System.err);
		System.exit(1);
	      }
	  }
	    
	try
	  {
	    PersistentByteMap b 
	      = PersistentByteMap.emptyPersistentByteMap(new File(s[1]), 
							 capacity, capacity*32);
	  }
	catch (Exception e)
	  {
	    System.err.println ("error: could not create " 
				+ s[1] + ": " + e.toString());
	    System.exit(2);
	  }
	return;
      }

    if (s[0].equals("-a") || s[0].equals("-f"))
      {
	// Add a jar file to a database, creating it if necessary.
	// Copies the database, adds the jar file to the copy, and
	// then renames the new database over the old.
	try
	  {
	    insist (s.length == 4);
	    File database = new File(s[1]);
	    database = database.getAbsoluteFile();
	    File jar = new File(s[2]);	
	    PersistentByteMap map; 
	    if (database.isFile())
	      map = new PersistentByteMap(database, 
					  PersistentByteMap.AccessMode.READ_ONLY);
	    else
	      map = PersistentByteMap.emptyPersistentByteMap(database, 
							     100, 100*32);
	    File soFile = new File(s[3]);
	    if (! s[0].equals("-f") && ! soFile.isFile())
	      throw new IllegalArgumentException(s[3] + " is not a file");
 	    map = addJar(jar, map, soFile);
	  }
	catch (Exception e)
	  {
	    System.err.println ("error: could not update " + s[1] 
				+ ": " + e.toString());
	    System.exit(2);
	  }
	return;
      }

    if (s[0].equals("-t"))
      {
	// Test
	try
	  {
	    insist (s.length == 2);
	    PersistentByteMap b 
	      = new PersistentByteMap(new File(s[1]),
				      PersistentByteMap.AccessMode.READ_ONLY);
	    Iterator iterator = b.iterator(PersistentByteMap.ENTRIES);
	
	    while (iterator.hasNext())
	      {
		PersistentByteMap.MapEntry entry 
		  = (PersistentByteMap.MapEntry)iterator.next();
		byte[] key = (byte[])entry.getKey();
		byte[] value = (byte[])b.get(key);
		if (! Arrays.equals (value, (byte[])entry.getValue()))
		  {
		    String err 
		      = ("Key " + bytesToString(key) + " at bucket " 
			 + entry.getBucket());
		  
		    throw new RuntimeException(err);
		  }
	      }
	  }
	catch (Exception e)
	  {
	    e.printStackTrace();
	    System.exit(3);
	  }
	return;
      }
	 
    if (s[0].equals("-m"))
      {
	// Merge databases.
	insist (s.length >= 3
		|| fileListFromStdin && s.length == 2);
	try
	  {
	    File database = new File(s[1]);
	    database = database.getAbsoluteFile();
	    File temp = File.createTempFile(database.getName(), "", 
					    database.getParentFile());
	    	
	    int newSize = 0;
	    int newStringTableSize = 0;
	    Fileset files = getFiles(s, 2, fileListFromStdin, 
				     filenameSeparator);
	    PersistentByteMap[] sourceMaps 
	      = new PersistentByteMap[files.size()];

	    // Scan all the input files, calculating worst case string
	    // table and hash table use.
	    {
	      Iterator it = files.iterator();
	      int i = 0;
	      while (it.hasNext())
		{
		  PersistentByteMap b 
		    = new PersistentByteMap((File)it.next(),
					    PersistentByteMap.AccessMode.READ_ONLY);
		  newSize += b.size();
		  newStringTableSize += b.stringTableSize();
		  sourceMaps[i++] = b;
		}
	    }
	    
	    newSize *= 1.5; // Scaling the new size by 1.5 results in
			    // fewer collisions.
	    PersistentByteMap map 
	      = PersistentByteMap.emptyPersistentByteMap
	      (temp, newSize, newStringTableSize);

	    for (int i = 0; i < sourceMaps.length; i++)
	      {
		if (verbose)
		  System.err.println("adding " + sourceMaps[i].size() 
				     + " elements from "
				     + sourceMaps[i].getFile());
		map.putAll(sourceMaps[i]);
	      }
	    map.close();
	    temp.renameTo(database);
	  }
	catch (Exception e)
	  {
	    e.printStackTrace();
	    System.exit(3);
	  }
	return;
      }

    if (s[0].equals("-l"))
      {
	// List a database.
	insist (s.length == 2);
	try
	  {
	    PersistentByteMap b 
	      = new PersistentByteMap(new File(s[1]),
				      PersistentByteMap.AccessMode.READ_ONLY);

	    System.out.println ("Capacity: " + b.capacity());
	    System.out.println ("Size: " + b.size());
	    System.out.println ();

	    System.out.println ("Elements: ");
	    Iterator iterator = b.iterator(PersistentByteMap.ENTRIES);
    
	    while (iterator.hasNext())
	      {
		PersistentByteMap.MapEntry entry 
		  = (PersistentByteMap.MapEntry)iterator.next();
		byte[] digest = (byte[])entry.getKey();
		System.out.print ("[" + entry.getBucket() + "] " 
				  + bytesToString(digest)
				  + " -> ");
		System.out.println (new String((byte[])entry.getValue()));
	      }
	  }
	catch (Exception e)
	  {
	    System.err.println ("error: could not list " 
				+ s[1] + ": " + e.toString());
	    System.exit(2);
	  }
	return;
      }

    if (s[0].equals("-d"))
      {
	// For testing only: fill the byte map with random data.
	insist (s.length == 2);
	try
	  {    
	    MessageDigest md = MessageDigest.getInstance("MD5");
	    PersistentByteMap b 
	      = new PersistentByteMap(new File(s[1]), 
				      PersistentByteMap.AccessMode.READ_WRITE);
	    int N = b.capacity();
	    byte[] bytes = new byte[1];
	    byte digest[] = md.digest(bytes);
	    for (int i = 0; i < N; i++)
	      {
		digest = md.digest(digest);
		b.put(digest, digest);
	      }
	  }
	catch (Exception e)
	  {
	    e.printStackTrace();
	    System.exit(3);
	  }	    
	return;
      }

    if (s[0].equals("-p"))
      {
	insist (s.length == 1 || s.length == 2);
	String result;
	
	if (s.length == 1)
	  result = System.getProperty("gnu.gcj.precompiled.db.path", "");
	else 
	  result = (s[1] 
		    + (s[1].endsWith(File.separator) ? "" : File.separator)
		    + getDbPathTail ());

	System.out.println (result);
	return;
      }

    usage(System.err);
    System.exit(1);	    
  }

  private static native String getDbPathTail ();
    
  private static void insist(boolean ok)
  {
    if (! ok)
      {
	usage(System.err);
	System.exit(1);
      }	    
  }

  private static void usage(PrintStream out)
  {
    out.println
      ("gcj-dbtool: Manipulate gcj map database files\n"
       + "\n"
       + "  Usage: \n"
       + "    gcj-dbtool -n file.gcjdb [size]     - Create a new gcj map database\n"
       + "    gcj-dbtool -a file.gcjdb file.jar file.so\n"
       + "            - Add the contents of file.jar to a gcj map database\n"
       + "    gcj-dbtool -f file.gcjdb file.jar file.so\n"
       + "            - Add the contents of file.jar to a gcj map database\n"
       + "    gcj-dbtool -t file.gcjdb            - Test a gcj map database\n"
       + "    gcj-dbtool -l file.gcjdb            - List a gcj map database\n"
       + "    gcj-dbtool [-][-0] -m dest.gcjdb [source.gcjdb]...\n"
       + "            - Merge gcj map databases into dest\n"
       + "              Replaces dest\n"
       + "              To add to dest, include dest in the list of sources\n"
       + "              If the first arg is -, read the list from stdin\n"
       + "              If the first arg is -0, filenames separated by nul\n"
       + "    gcj-dbtool -p [LIBDIR]              - Print default database name"
       );
  }

  // Add a jar to a map.  This copies the map first and returns a
  // different map that contains the data.  The original map is
  // closed.

  private static PersistentByteMap 
  addJar(File f, PersistentByteMap b, File soFile)
    throws Exception
  {
    MessageDigest md = MessageDigest.getInstance("MD5");

    JarFile jar = new JarFile (f);

    int count = 0;
    {
      Enumeration entries = jar.entries();      
      while (entries.hasMoreElements())
	{
	  JarEntry classfile = (JarEntry)entries.nextElement();
	  if (classfile.getName().endsWith(".class"))
	    count++;
	}
    }

    if (verbose)
      System.err.println("adding " + count + " elements from "
			 + f + " to " + b.getFile());
    
    // Maybe resize the destination map.  We're allowing plenty of
    // extra space by using a loadFactor of 2.  
    b = resizeMap(b, (b.size() + count) * 2, true);

    Enumeration entries = jar.entries();

    byte[] soFileName = soFile.getCanonicalPath().getBytes("UTF-8");
    while (entries.hasMoreElements())
      {
	JarEntry classfile = (JarEntry)entries.nextElement();
	if (classfile.getName().endsWith(".class"))
	  {
	    InputStream str = jar.getInputStream(classfile);
	    long length = classfile.getSize();
	    if (length == -1)
	      throw new EOFException();

	    byte[] data = new byte[length];
	    int pos = 0;
	    while (length - pos > 0)
	      {
		int len = str.read(data, pos, (int)(length - pos));
		if (len == -1)
		  throw new EOFException("Not enough data reading from: "
					 + classfile.getName());
		pos += len;
	      }
	    b.put(md.digest(data), soFileName);
	  }
      }
    return b;
  }    

  // Resize a map by creating a new one with the same data and
  // renaming it.  If close is true, close the original map.

  static PersistentByteMap resizeMap(PersistentByteMap m, int newCapacity, boolean close)
    throws IOException, IllegalAccessException
  {
    newCapacity = Math.max(m.capacity(), newCapacity);
    File name = m.getFile();
    File copy = File.createTempFile(name.getName(), "", name.getParentFile());
    try
      {
	PersistentByteMap dest 
	  = PersistentByteMap.emptyPersistentByteMap
	  (copy, newCapacity, newCapacity*32);
	dest.putAll(m);
	dest.force();
	if (close)
	  m.close();
	copy.renameTo(name);
	return dest;
      }
    catch (Exception e)
      {
	copy.delete();
      }
    return null;
  }
    
	 
  static String bytesToString(byte[] b)
  {
    StringBuffer hexBytes = new StringBuffer();
    int length = b.length;
    for (int i = 0; i < length; ++i)
      hexBytes.append(Integer.toHexString(b[i] & 0xff));
    return hexBytes.toString();
  }


  // Return a Fileset, either from a String array or from System.in,
  // depending on fileListFromStdin.
  private static final Fileset getFiles(String[] s, int startPos,
					boolean fileListFromStdin,
					char separator)
  {
    if (fileListFromStdin)
      return new Fileset(System.in, separator);
    else
      return new Fileset(s, startPos, s.length);
  }
}

// Parse a stream into tokens.  The separator can be any char, and
// space is equivalent to any whitepace character.
class Tokenizer
{
  final Reader r;
  final char separator;

  Tokenizer(Reader r, char separator)
  {
    this.r = r;
    this.separator = separator;
  }

  boolean isSeparator(int c)
  {
    if (Character.isWhitespace(separator))
      return Character.isWhitespace((char)c);
    else
      return c == separator;
  }

  // Parse a token from the input stream.  Return the empty string
  // when the stream is exhausted.
  String nextToken ()
  {
    StringBuffer buf = new StringBuffer();
    int c;
    try
      {
	while ((c = r.read()) != -1)
	  {
	    if (! isSeparator(c))
	      {
		buf.append((char)c);
		break;
	      }
	  }
	while ((c = r.read()) != -1)
	  {
	    if (isSeparator(c))
	      break;
	    else
	      buf.append((char)c);
	  }
      }
    catch (java.io.IOException e)
      {
      }
    return buf.toString();
  }
}

// A Fileset is a container for a set of files; it can be created
// either from a string array or from an input stream, given a
// separator character.
class Fileset
{
  LinkedHashSet files = new LinkedHashSet();
  
  Fileset (String[] s, int start, int end)
  {
    for (int i = start; i < end; i++)
      {
	files.add(new File(s[i]));
      }
  }

  Fileset (InputStream is, char separator)
  {
    Reader r = new BufferedReader(new InputStreamReader(is));
    Tokenizer st = new Tokenizer(r, separator);
    String name;
    while (! "".equals(name = st.nextToken()))
      files.add(new File(name));
  }

  Iterator iterator()
  {
    return files.iterator();
  }

  int size()
  {
    return files.size();
  }
}
