/*
 * Copyright (c) 2008, 2009, Oracle and/or its affiliates. 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.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */
package com.sun.tools.corba.se.logutil;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;

import java.util.Arrays;
import java.util.Date;
import java.util.Formatter;
import java.util.List;
import java.util.Queue;

public class MC {

  private static final String VERSION = "1.0";

  private static final List<String> SUN_EXCEPTION_GROUPS = Arrays.asList(new String[]
    { "SUNBASE", "ORBUTIL", "ACTIVATION", "NAMING", "INTERCEPTORS", "POA", "IOR", "UTIL" });

  private static final List<String> EXCEPTIONS = Arrays.asList(new String[]
    { "UNKNOWN", "BAD_PARAM", "NO_MEMORY", "IMP_LIMIT", "COMM_FAILURE", "INV_OBJREF", "NO_PERMISSION",
      "INTERNAL", "MARSHAL", "INITIALIZE", "NO_IMPLEMENT", "BAD_TYPECODE", "BAD_OPERATION", "NO_RESOURCES",
      "NO_RESPONSE", "PERSIST_STORE", "BAD_INV_ORDER", "TRANSIENT", "FREE_MEM", "INV_IDENT", "INV_FLAG",
      "INTF_REPOS", "BAD_CONTEXT", "OBJ_ADAPTER", "DATA_CONVERSION", "OBJECT_NOT_EXIST", "TRANSACTION_REQUIRED",
      "TRANSACTION_ROLLEDBACK", "INVALID_TRANSACTION", "INV_POLICY", "CODESET_INCOMPATIBLE", "REBIND",
      "TIMEOUT", "TRANSACTION_UNAVAILABLE", "BAD_QOS", "INVALID_ACTIVITY", "ACTIVITY_COMPLETED",
      "ACTIVITY_REQUIRED" });

  /**
   * Read the minor codes from the input file and
   * write out a resource file.
   *
   * @param inFile the file to read the codes from.
   * @param outDir the directory to write the resource file to.
   * @throws FileNotFoundException if the input file can not be found.
   * @throws IOException if an I/O error occurs.
   */
  private void makeResource(String inFile, String outDir)
  throws FileNotFoundException, IOException {
    writeResource(outDir, new Input(inFile));
  }

  /**
   * Create a new Java source file using the specified Scheme input file,
   * and writing the result to the given output directory.
   *
   * @param inFile the file to read the data from.
   * @param outDir the directory to write the Java class to.
   * @throws FileNotFoundException if the input file can not be found.
   * @throws IOException if an I/O error occurs.
   */
  private void makeClass(String inFile, String outDir)
  throws FileNotFoundException, IOException {
    writeClass(inFile, outDir, new Input(inFile));
  }

  /**
   * Writes out a Java source file using the data from the given
   * {@link Input} object.  The result is written to {@code outDir}.
   * The name of the input file is just used in the header of the
   * resulting source file.
   *
   * @param inFile the name of the file the data was read from.
   * @param outDir the directory to write the Java class to.
   * @param input the parsed input data.
   * @throws FileNotFoundException if the output file can't be written.
   */
  private void writeClass(String inFile, String outDir, Input input)
    throws FileNotFoundException {
    String packageName = input.getPackageName();
    String className = input.getClassName();
    String groupName = input.getGroupName();
    Queue<InputException> exceptions = input.getExceptions();
    FileOutputStream file = new FileOutputStream(outDir + File.separator + className + ".java");
    IndentingPrintWriter pw = new IndentingPrintWriter(file);

    writeClassHeader(inFile, groupName, pw);
    pw.printMsg("package @ ;", packageName);
    pw.println();
    pw.println("import java.util.logging.Logger ;");
    pw.println("import java.util.logging.Level ;");
    pw.println();
    pw.println("import org.omg.CORBA.OMGVMCID ;");
    pw.println( "import com.sun.corba.se.impl.util.SUNVMCID ;");
    pw.println( "import org.omg.CORBA.CompletionStatus ;");
    pw.println( "import org.omg.CORBA.SystemException ;");
    pw.println();
    pw.println( "import com.sun.corba.se.spi.orb.ORB ;");
    pw.println();
    pw.println( "import com.sun.corba.se.spi.logging.LogWrapperFactory;");
    pw.println();
    pw.println( "import com.sun.corba.se.spi.logging.LogWrapperBase;");
    pw.println();
    writeImports(exceptions, pw);
    pw.println();
    pw.indent();
    pw.printMsg("public class @ extends LogWrapperBase {", className);
    pw.println();
    pw.printMsg("public @( Logger logger )", className);
    pw.indent();
    pw.println( "{");
    pw.undent();
    pw.println( "super( logger ) ;");
    pw.println( "}");
    pw.println();
    pw.flush();
    writeFactoryMethod(className, groupName, pw);
    writeExceptions(groupName, exceptions, className, pw);
    pw.undent();
    pw.println( );
    pw.println( "}");
    pw.flush();
    pw.close();
  }

  /**
   * Writes out the header of a Java source file.
   *
   * @param inFile the input file the file was generated from.
   * @param groupName the group of exceptions the Java source file is for.
   * @param pw the print writer used to write the output.
   */
  private void writeClassHeader(String inFile, String groupName,
                                IndentingPrintWriter pw) {
    if (groupName.equals("OMG"))
      pw.println("// Log wrapper class for standard exceptions");
    else
      pw.printMsg("// Log wrapper class for Sun private system exceptions in group @",
                  groupName);
    pw.println("//");
    pw.printMsg("// Generated by MC.java version @, DO NOT EDIT BY HAND!", VERSION);
    pw.printMsg("// Generated from input file @ on @", inFile, new Date());
    pw.println();
  }

  /**
   * Write out the import list for the exceptions.
   *
   * @param groups the exceptions that were parsed.
   * @param pw the {@link IndentingPrintWriter} for writing to the file.
   */
  private void writeImports(Queue<InputException> exceptions,
                            IndentingPrintWriter pw) {
    if (exceptions == null)
      return;
    for (InputException e : exceptions)
      pw.println("import org.omg.CORBA." + e.getName() + " ;");
  }

  /**
   * Write out the factory method for this group of exceptions.
   *
   * @param className the name of the generated class.
   * @param groupName the name of this group of exceptions.
   * @param pw the {@link IndentingPrintWriter} for writing to the file.
   */
  private void writeFactoryMethod(String className, String groupName,
                                  IndentingPrintWriter pw) {
    pw.indent();
    pw.println( "private static LogWrapperFactory factory = new LogWrapperFactory() {");
    pw.println( "public LogWrapperBase create( Logger logger )" );
    pw.indent();
    pw.println( "{");
    pw.undent();
    pw.printMsg("return new @( logger ) ;", className);
    pw.undent();
    pw.println( "}" );
    pw.println( "} ;" );
    pw.println();
    pw.printMsg("public static @ get( ORB orb, String logDomain )", className);
    pw.indent();
    pw.println( "{");
    pw.indent();
    pw.printMsg( "@ wrapper = ", className);
    pw.indent();
    pw.printMsg( "(@) orb.getLogWrapper( logDomain, ", className);
    pw.undent();
    pw.undent();
    pw.printMsg( "\"@\", factory ) ;", groupName);
    pw.undent();
    pw.println( "return wrapper ;" );
    pw.println( "} " );
    pw.println();
    pw.printMsg( "public static @ get( String logDomain )", className);
    pw.indent();
    pw.println( "{");
    pw.indent();
    pw.printMsg( "@ wrapper = ", className);
    pw.indent();
    pw.printMsg( "(@) ORB.staticGetLogWrapper( logDomain, ", className);
    pw.undent();
    pw.undent();
    pw.printMsg( "\"@\", factory ) ;", groupName);
    pw.undent();
    pw.println( "return wrapper ;" );
    pw.println( "} " );
    pw.println();
  }

  /**
   * Writes out the exceptions themselves.
   *
   * @param groupName the name of this group of exceptions.
   * @param exceptions the exceptions to write out.
   * @param className the name of the generated class.
   * @param pw the {@link IndentingPrintWriter} for writing to the file.
   */
  private void writeExceptions(String groupName, Queue<InputException> exceptions,
                               String className, IndentingPrintWriter pw) {
    for (InputException e : exceptions) {
      pw.println("///////////////////////////////////////////////////////////");
      pw.printMsg("// @", e.getName());
      pw.println("///////////////////////////////////////////////////////////");
      pw.println();
      for (InputCode c : e.getCodes())
        writeMethods(groupName, e.getName(), c.getName(), c.getCode(),
                     c.getLogLevel(), className, StringUtil.countArgs(c.getMessage()), pw);
      pw.flush();
    }
  }

  /**
   * Writes out the methods for a particular error.
   *
   * @param groupName the name of this group of exceptions.
   * @param exceptionName the name of this particular exception.
   * @param errorName the name of this particular error.
   * @param code the minor code for this particular error.
   * @param ident the name of the error in mixed-case identifier form.
   * @param level the level at which to place log messages.
   * @param className the name of the class for this group of exceptions.
   * @param numParams the number of parameters the detail message takes.
   * @param pw the print writer for writing to the file.
   */
  private void writeMethods(String groupName, String exceptionName, String errorName,
                            int code, String level, String className, int numParams,
                            IndentingPrintWriter pw) {
    String ident = StringUtil.toMixedCase(errorName);
    pw.printMsg("public static final int @ = @ ;", errorName, getBase(groupName, code));
    pw.println();
    pw.flush();
    writeMethodStatusCause(groupName, exceptionName, errorName, ident, level,
                           numParams, className, pw);
    pw.println();
    pw.flush();
    writeMethodStatus(exceptionName, ident, numParams, pw);
    pw.println();
    pw.flush();
    writeMethodCause(exceptionName, ident, numParams, pw);
    pw.println();
    pw.flush();
    writeMethodNoArgs(exceptionName, ident, numParams, pw);
    pw.println();
    pw.flush();
  }

  /**
   * Writes out a method for an error that takes a
   * {@link org.omg.CORBA.CompletionStatus} and a cause.
   *
   * @param groupName the name of this group of exceptions.
   * @param exceptionName the name of this particular exception.
   * @param errorName the name of this particular error.
   * @param ident the name of the error in mixed-case identifier form.
   * @param logLevel the level at which to place log messages.
   * @param numParams the number of parameters the detail message takes.
   * @param className the name of the class for this group of exceptions.
   * @param pw the print writer for writing to the file.
   */
  private void writeMethodStatusCause(String groupName, String exceptionName,
                                      String errorName, String ident,
                                      String logLevel, int numParams,
                                      String className, IndentingPrintWriter pw) {
    pw.indent();
    pw.printMsg( "public @ @( CompletionStatus cs, Throwable t@) {", exceptionName,
                 ident, makeDeclArgs(true, numParams));
    pw.printMsg( "@ exc = new @( @, cs ) ;", exceptionName, exceptionName, errorName);
    pw.indent();
    pw.println( "if (t != null)" );
    pw.undent();
    pw.println( "exc.initCause( t ) ;" );
    pw.println();
    pw.indent();
    pw.printMsg( "if (logger.isLoggable( Level.@ )) {", logLevel);
    if (numParams > 0) {
      pw.printMsg( "Object[] parameters = new Object[@] ;", numParams);
      for (int a = 0; a < numParams; ++a)
        pw.printMsg("parameters[@] = arg@ ;", a, a);
    } else
      pw.println( "Object[] parameters = null ;");
    pw.indent();
    pw.printMsg( "doLog( Level.@, \"@.@\",", logLevel, groupName, ident);
    pw.undent();
    pw.undent();
    pw.printMsg( "parameters, @.class, exc ) ;", className);
    pw.println( "}");
    pw.println();

    pw.undent();
    pw.println( "return exc ;");
    pw.println( "}");
  }

  /**
   * Writes out a method for an error that takes a
   * {@link org.omg.CORBA.CompletionStatus}.
   *
   * @param exceptionName the name of this particular exception.
   * @param ident the name of the error in mixed-case identifier form.
   * @param numParams the number of parameters the detail message takes.
   * @param pw the print writer for writing to the file.
   */
  private void writeMethodStatus(String exceptionName, String ident,
                                 int numParams, IndentingPrintWriter pw) {
    pw.indent();
    pw.printMsg("public @ @( CompletionStatus cs@) {", exceptionName,
                ident, makeDeclArgs(true, numParams));
    pw.undent();
    pw.printMsg("return @( cs, null@ ) ;", ident, makeCallArgs(true, numParams));
    pw.println("}");
  }

  /**
   * Writes out a method for an error that takes a cause.
   *
   * @param exceptionName the name of this particular exception.
   * @param ident the name of the error in mixed-case identifier form.
   * @param numParams the number of parameters the detail message takes.
   * @param pw the print writer for writing to the file.
   */
  private void writeMethodCause(String exceptionName, String ident,
                                int numParams, IndentingPrintWriter pw) {
    pw.indent();
    pw.printMsg("public @ @( Throwable t@) {", exceptionName, ident,
                makeDeclArgs(true, numParams));
    pw.undent();
    pw.printMsg("return @( CompletionStatus.COMPLETED_NO, t@ ) ;", ident,
                makeCallArgs(true, numParams));
    pw.println("}");
  }

  /**
   * Writes out a method for an error that takes no arguments.
   *
   * @param exceptionName the name of this particular exception.
   * @param ident the name of the error in mixed-case identifier form.
   * @param numParams the number of parameters the detail message takes.
   * @param pw the print writer for writing to the file.
   */
  private void writeMethodNoArgs(String exceptionName, String ident,
                                 int numParams, IndentingPrintWriter pw) {

    pw.indent();
    pw.printMsg("public @ @( @) {", exceptionName, ident,
                makeDeclArgs(false, numParams));
    pw.undent();
    pw.printMsg("return @( CompletionStatus.COMPLETED_NO, null@ ) ;",
                ident, makeCallArgs(true, numParams));
    pw.println("}");
  }

  /**
   * Returns a list of comma-separated arguments with type declarations.
   *
   * @param leadingComma true if the list should start with a comma.
   * @param numArgs the number of arguments to generate.
   * @return the generated string.
   */
  private String makeDeclArgs(boolean leadingComma, int numArgs) {
    return makeArgString("Object arg", leadingComma, numArgs);
  }

  /**
   * Returns a list of comma-separated arguments without type declarations.
   *
   * @param leadingComma true if the list should start with a comma.
   * @param numArgs the number of arguments to generate.
   * @return the generated string.
   */
  private String makeCallArgs(boolean leadingComma, int numArgs) {
    return makeArgString("arg", leadingComma, numArgs);
  }

  /**
   * Returns a list of comma-separated arguments.
   *
   * @param prefixString the string with which to prefix each argument.
   * @param leadingComma true if the list should start with a comma.
   * @param numArgs the number of arguments to generate.
   * @return the generated string.
   */
  private String makeArgString(String prefixString, boolean leadingComma,
                               int numArgs) {
    if (numArgs == 0)
      return " ";
    if (numArgs == 1) {
      if (leadingComma)
        return ", " + prefixString + (numArgs - 1);
      else
        return " " + prefixString + (numArgs - 1);
    }
    return makeArgString(prefixString, leadingComma, numArgs - 1) +
      ", " + prefixString + (numArgs - 1);
  }

  /**
   * Returns the {@link String} containing the calculation of the
   * error code.
   *
   * @param groupName the group of exception to which the code belongs.
   * @param code the minor code number representing the exception within the group.
   * @return the unique error code.
   */
  private String getBase(String groupName, int code) {
    if (groupName.equals("OMG"))
      return "OMGVMCID.value + " + code;
    else
      return "SUNVMCID.value + " + (code + getSunBaseNumber(groupName));
  }

  /**
   * Returns the base number for Sun-specific exceptions.
   *
   * @return the base number.
   */
  private int getSunBaseNumber(String groupName) {
    return 200 * SUN_EXCEPTION_GROUPS.indexOf(groupName);
  }

  /**
   * Writes out a resource file using the data from the given
   * {@link Input} object.  The result is written to {@code outDir}.
   *
   * @param outDir the directory to write the Java class to.
   * @param input the parsed input data.
   * @throws FileNotFoundException if the output file can't be written.
   */
  private void writeResource(String outDir, Input input)
    throws FileNotFoundException {
    FileOutputStream file = new FileOutputStream(outDir + File.separator +
                                                 input.getClassName() + ".resource");
    IndentingPrintWriter pw = new IndentingPrintWriter(file);
    String groupName = input.getGroupName();
    for (InputException e : input.getExceptions()) {
      String exName = e.getName();
      for (InputCode c : e.getCodes()) {
        String ident = StringUtil.toMixedCase(c.getName());
        pw.printMsg("@.@=\"@: (@) @\"", groupName, ident,
                    getMessageID(groupName, exName, c.getCode()), exName, c.getMessage());
      }
      pw.flush();
    }
    pw.close();
  }

  /**
   * Returns the message ID corresponding to the given group name,
   * exception name and error code.
   *
   * @param groupName the name of the group of exceptions.
   * @param exception the name of the particular exception.
   * @param code an error code from the given exception.
   * @return the message ID.
   */
  private String getMessageID(String groupName, String exceptionName, int code) {
    if (groupName.equals("OMG"))
      return getStandardMessageID(exceptionName, code);
    else
      return getSunMessageID(groupName, exceptionName, code);
  }

  /**
   * Returns the standard (OMG) message ID corresponding to the given
   * exception name and error code.
   *
   * @param exceptionName the name of the particular exception.
   * @param code an error code from the given exception.
   * @return the message ID.
   */
  private String getStandardMessageID(String exceptionName, int code) {
    return new Formatter().format("IOP%s0%04d", getExceptionID(exceptionName),
                                  code).toString();
  }

  /**
   * Returns the Sun message ID corresponding to the given group name,
   * exception name and error code.
   *
   * @param groupName the name of the group of exceptions.
   * @param exceptionName the name of the particular exception.
   * @param code an error code from the given exception.
   * @return the message ID.
   */
  private String getSunMessageID(String groupName, String exceptionName, int code) {
    return new Formatter().format("IOP%s1%04d", getExceptionID(exceptionName),
                                  getSunBaseNumber(groupName) + code).toString();
  }

  /**
   * Returns the exception ID corresponding to the given exception name.
   *
   * @param exceptionName the name of the particular exception.
   * @return the message ID.
   */
  private String getExceptionID(String exceptionName) {
    return new Formatter().format("%03d", EXCEPTIONS.indexOf(exceptionName)).toString();
  }

  /**
   * Entry point for running the generator from the command
   * line.  Users can specify either "make-class" or "make-resource"
   * as the first argument to generate the specified type of file.
   *
   * @param args the command-line arguments.
   * @throws FileNotFoundException if the input file can not be found.
   * @throws IOException if an I/O error occurs.
   */
  public static void main(String[] args)
    throws FileNotFoundException, IOException
  {
    if (args.length < 3)
      {
        System.err.println("(make-class|make-resource) <input file> <output dir>");
        System.exit(-1);
      }
    if (args[0].equals("make-class"))
      new MC().makeClass(args[1], args[2]);
    else if (args[0].equals("make-resource"))
      new MC().makeResource(args[1], args[2]);
    else
      System.err.println("Invalid command: " + args[0]);
  }

}
