/*
 * JOnAS: Java(TM) Open Application Server
 * Copyright (C) 1999 Bull S.A.
 * Contact: jonas-team@ow2.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307
 * USA
 *
 *
 * --------------------------------------------------------------------------
 * $Id$
 * --------------------------------------------------------------------------
 */

package org.ow2.jonas.commands.wrapper;

import java.util.StringTokenizer;
/**
 * This class is called by 'jonas start' command to generate
 * properties for the Java Service Wrapper configuration file.
 */
public class GenerateWrapperConf
{

  /**
   * Generate property file for Java Service Wrapper.
   * <p>
   * GenerateWrapperConf parses CLASSPATH or an array of JAVA options
   * for the current JONAS_BASEW
   * into individual property definitions for the Java Service Wrapper
   * configuration file.
   * <p>
   * <pre>
   * Usage: java org.ow2.jonas.commands.wrapper.GenerateWrapperConf
   *        [-h | -?] to display usage
   *        [-d <delimiter>] to define delimiter for StringTokenizer
   *                         <delimiter> is a string of one or more
   *                         characters to be used by StringTokenizer
   *        [-i <index>]     to define initial index for generated property
   *                         <index> is the initial value to be appended
   *                         to the generated property.name entries
   *        property.name    name of property(s) to be generated
   *        args             string(s) to be parsed into properties
   * </pre>
   * <p>
   * Refer to Java Service Wrapper documentation
   * for details on configuration file format.
   * http://wrapper.tanukisoftware.org
   */
  String propertyName = null;
  int index = 1;

  /**
   * Display command syntax.
   */
  void syntax()
  {
    System.err.println("syntax: GenerateWrapperConf [-d <delimiters>] [-i <indx>] property.name args");
    System.exit(1);
  }

  /**
   * Display command syntax with unrecognized command line argument
   */
  void syntax(String arg)
  {
    System.err.println("GenerateWrapperConf: unrecognized argument '" + arg + "'");
    syntax();
  }

  /**
   * Display command syntax with exception message
   */
  void syntax(Exception e)
  {
    System.err.println(e.toString());
    syntax();
  }

  /**
   * Generate Wrapper.conf property
   */
  void generateKey(String val)
  {
    if (val.contains(" ")) {
      int equals = val.indexOf('=');
      if (equals == -1) {
        // This one should not be escaped, see http://jira.ow2.org/browse/JONAS-36
        System.out.println (propertyName + "." + index + "=" + val);
      } else {
        // Put the quotes just after the "="
        equals++;
        System.out.println (propertyName + "." + index + "=" + val.substring(0, equals) + "\"" + val.substring(equals) + "\"");
      }
    } else {
      System.out.println (propertyName + "." + index + "=" + val);
    }
    index += 1;
  }

  /**
   * Process command line args and generate requested
   * wrapper.conf property entries to STDOUT.
   */
    void run(String[] args)
    {
    String delimiter = null;
    int i = 0; // index into args[]

    for ( ; i < args.length; i++)
    {
      if (args[i].charAt(0) != '-') break;
      try {
        switch(args[i].charAt(1))
        {
          case 'h':
          case '?':
            usage();

          case 'd':
            delimiter = args[++i];
            break;

          case 'i':
            index = Integer.parseInt(args[++i]);
            break;

          default:
            syntax(args[i]);
        }
      }
      catch (StringIndexOutOfBoundsException e) {
        syntax(args[i]);
      }
      catch (NumberFormatException e) {
        syntax(e);
      }
    }

    // first positional arg after -d is the property.name
    if ((args.length - i) < 2) syntax();
    propertyName = args[i];
    i += 1;

    if (delimiter == null)  // process array of individual args
    {
      for ( ; i < args.length; ++i) generateKey(args[i]);
    }

    else  // use StringTokenizer to parse single string
    {
      StringTokenizer st = new StringTokenizer(args[i], delimiter);
      while (st.hasMoreTokens()) generateKey(st.nextToken());
      i += 1;
    }

    if ((args.length - i) > 0) syntax();
    }

  /**
   * run a new instance of the class
   */
  public static void main(String[] args)
  {
    if (args.length == 0)
      usage();
    else
      new GenerateWrapperConf().run(args);
  }

  /**
   * Display syntax
   */
  private static void usage()
  {
    System.out.println(
      "\nUsage: java org.objectweb.java.tools.GenerateWrapperConf [-h | -?]\n" +
      "           [-d <delimiters>] [-i <index>] property.name args\n" +
      "\n" +
      "  -h or -? display this help message.\n" +
      "  -d <delimiters> specifies a string of delimiters used to parse\n" +
      "                  args into individual tokens.\n" +
      "  -i <index>      specifies the initial index for generated property\n" +
      "                  values.  The default value is 1.\n" +
      "  property.name   specifies the property name to be generated.\n" +
      "                  Property names for the individual tokens are formed\n" +
      "                  as 'property.name.index' where 'index' is incremented\n" +
      "                  for each token.\n" +
      "  args            Either a single string to be parsed using StringTokenizer\n" +
      "                  and the delimiter specified by the -d option.\n" +
      "                  This form is used to process the CLASSPATH variable.\n\n" +
      "                  Or, an array of strings to be processed as individual tokens.\n" +
      "                  This form is used to process JAVA_OPTS style variables.\n"
    );
    System.exit(1);
  }
}