/*
 * ============================================================================
 *                   The Apache Software License, Version 1.1
 * ============================================================================
 *
 *    Copyright (C) 1999 The Apache Software Foundation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modifica-
 * tion, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of  source code must  retain the above copyright  notice,
 *    this list of conditions and the following disclaimer.
 *
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 *
 * 3. The end-user documentation included with the redistribution, if any, must
 *    include  the following  acknowledgment:  "This product includes  software
 *    developed  by the  Apache Software Foundation  (http://www.apache.org/)."
 *    Alternately, this  acknowledgment may  appear in the software itself,  if
 *    and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "log4j" and  "Apache Software Foundation"  must not be used to
 *    endorse  or promote  products derived  from this  software without  prior
 *    written permission. For written permission, please contact
 *    apache@apache.org.
 *
 * 5. Products  derived from this software may not  be called "Apache", nor may
 *    "Apache" appear  in their name,  without prior written permission  of the
 *    Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
 * FITNESS  FOR A PARTICULAR  PURPOSE ARE  DISCLAIMED.  IN NO  EVENT SHALL  THE
 * APACHE SOFTWARE  FOUNDATION  OR ITS CONTRIBUTORS  BE LIABLE FOR  ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL,  EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLU-
 * DING, BUT NOT LIMITED TO, PROCUREMENT  OF SUBSTITUTE GOODS OR SERVICES; LOSS
 * OF USE, DATA, OR  PROFITS; OR BUSINESS  INTERRUPTION)  HOWEVER CAUSED AND ON
 * ANY  THEORY OF LIABILITY,  WHETHER  IN CONTRACT,  STRICT LIABILITY,  OR TORT
 * (INCLUDING  NEGLIGENCE OR  OTHERWISE) ARISING IN  ANY WAY OUT OF THE  USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * This software  consists of voluntary contributions made  by many individuals
 * on  behalf of the Apache Software  Foundation.  For more  information on the
 * Apache Software Foundation, please see <http://www.apache.org/>.
 *
 */

package org.apache.log4j.pattern;

import org.apache.log4j.Layout;
import org.apache.log4j.helpers.AbsoluteTimeDateFormat;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.helpers.OptionConverter;

import java.util.Hashtable;


// Contributors:   Nelson Minar <(nelson@monkey.org>
//                 Igor E. Poteryaev <jah@mail.ru>
//                 Reinhard Deschler <reinhard.deschler@web.de>

/**
   Most of the work of the {@link org.apache.log4j.PatternLayout} class
   is delegated to the PatternParser class.

   <p>It is this class that parses conversion patterns and creates
   a chained list of {@link OptionConverter OptionConverters}.

   @author <a href=mailto:"cakalijp@Maritz.com">James P. Cakalic</a>
   @author Ceki G&uuml;lc&uuml;
   @author Anders Kristensen

   @since 0.8.2
*/
public class PatternParser {
  private static final char ESCAPE_CHAR = '%';
  private static final int LITERAL_STATE = 0;
  private static final int CONVERTER_STATE = 1;
  private static final int MINUS_STATE = 2;
  private static final int DOT_STATE = 3;
  private static final int MIN_STATE = 4;
  private static final int MAX_STATE = 5;
  static final int FULL_LOCATION_CONVERTER = 1000;
  static final int METHOD_LOCATION_CONVERTER = 1001;
  static final int CLASS_LOCATION_CONVERTER = 1002;
  static final int LINE_LOCATION_CONVERTER = 1003;
  static final int FILE_LOCATION_CONVERTER = 1004;
  static final int RELATIVE_TIME_CONVERTER = 2000;
  static final int THREAD_CONVERTER = 2001;
  static final int LEVEL_CONVERTER = 2002;
  static final int NDC_CONVERTER = 2003;
  static final int MESSAGE_CONVERTER = 2004;
  int state;
  protected StringBuffer currentLiteral = new StringBuffer(32);
  protected int patternLength;
  protected int i;
  PatternConverter head;
  PatternConverter tail;
  protected FormattingInfo formattingInfo = new FormattingInfo();
  protected String pattern;
  Hashtable converterRegistry;

  public PatternParser(String pattern) {
    this.pattern = pattern;
    patternLength = pattern.length();
    state = LITERAL_STATE;
  }

  private void addToList(PatternConverter pc) {
    if (head == null) {
      head = tail = pc;
    } else {
      tail.next = pc;
      tail = pc;
    }
  }

  /** Extract the converter identifier found at position i.
   *
   * After this function returns, the variable i will point to the
   * first char after the end of the converter identifier.
   *
   * If i points to a char which is not a character acceptable at the
   * start of a unicode identifier, the value null is returned.
   *
   */
  protected String extractConverter() {
    StringBuffer convBuf = new StringBuffer(16);

    if(i >= patternLength) {
    	// the pattern converter was the last character...
    	return null;
    }

    char c = pattern.charAt(i);

    if (Character.isUnicodeIdentifierStart(c)) {
      convBuf.append(c);
    } else {
      return null;
    }

    while (
      (++i < patternLength)
        && Character.isUnicodeIdentifierPart(pattern.charAt(i))) {
      convBuf.append(pattern.charAt(i));
    }

    return convBuf.toString();
  }

  /**
   * Returns the option, null if not in the expected format.
   */
  protected String extractOption() {
    if ((i < patternLength) && (pattern.charAt(i) == '{')) {
      int end = pattern.indexOf('}', i);

      if (end > i) {
        String r = pattern.substring(i + 1, end);
        i = end + 1;

        return r;
      }
    }

    return null;
  }

  public PatternConverter parse() {
    char c;
    i = 0;

    while (i < patternLength) {
      c = pattern.charAt(i++);

      switch (state) {
      case LITERAL_STATE:

        // In literal state, the last char is always a literal.
        if (i == patternLength) {
          currentLiteral.append(c);

          continue;
        }

        if (c == ESCAPE_CHAR) {
          // peek at the next char.
          switch (pattern.charAt(i)) {
          case ESCAPE_CHAR:
            currentLiteral.append(c);
            i++; // move pointer

            break;

          case 'n':
            currentLiteral.append(Layout.LINE_SEP);
            i++; // move pointer

            break;

          default:

            if (currentLiteral.length() != 0) {
              addToList(
                new LiteralPatternConverter(currentLiteral.toString()));

              //LogLog.debug("Parsed LITERAL converter: \""
              //           +currentLiteral+"\".");
            }

            currentLiteral.setLength(0);
            currentLiteral.append(c); // append %
            state = CONVERTER_STATE;
            formattingInfo.reset();
          }
        } else {
          currentLiteral.append(c);
        }

        break;

      case CONVERTER_STATE:
        currentLiteral.append(c);

        switch (c) {
        case '-':
          formattingInfo.leftAlign = true;

          break;

        case '.':
          state = DOT_STATE;

          break;

        default:

          if ((c >= '0') && (c <= '9')) {
            formattingInfo.min = c - '0';
            state = MIN_STATE;
          } else {
            finalizeConverter(c);
          }
        } // switch

        break;

      case MIN_STATE:
        currentLiteral.append(c);

        if ((c >= '0') && (c <= '9')) {
          formattingInfo.min = (formattingInfo.min * 10) + (c - '0');
        } else if (c == '.') {
          state = DOT_STATE;
        } else {
          finalizeConverter(c);
        }

        break;

      case DOT_STATE:
        currentLiteral.append(c);

        if ((c >= '0') && (c <= '9')) {
          formattingInfo.max = c - '0';
          state = MAX_STATE;
        } else {
          LogLog.error(
            "Error occured in position " + i
            + ".\n Was expecting digit, instead got char \"" + c + "\".");
          state = LITERAL_STATE;
        }

        break;

      case MAX_STATE:
        currentLiteral.append(c);

        if ((c >= '0') && (c <= '9')) {
          formattingInfo.max = (formattingInfo.max * 10) + (c - '0');
        } else {
          finalizeConverter(c);
          state = LITERAL_STATE;
        }

        break;
      } // switch
    }

    // while
    if (currentLiteral.length() != 0) {
      addToList(new LiteralPatternConverter(currentLiteral.toString()));

      //LogLog.debug("Parsed LITERAL converter: \""+currentLiteral+"\".");
    }

    return head;
  }

  String findConverterClass(String converterId) {
    if (converterRegistry != null) {
      String r = (String) converterRegistry.get(converterId);

      if (r != null) {
        return r;
      }
    }

    return null;
  }

  protected void finalizeConverter(char c) {
    PatternConverter pc = null;

	  //System.out.println("============================");
    

    String converterId = extractConverter();

    //System.out.println("==============[" + converterId + "]");
    //System.out.println("c is [" + c + "]");

    String className = (String) findConverterClass(converterId);

    String option = extractOption();
    //System.out.println("Option is [" + option + "]");


    if (className != null) {
      pc =
        (PatternConverter) OptionConverter.instantiateByClassName(
          className, PatternConverter.class, null);
    } else {
      switch (c) {
      case 'c':
        pc = new LoggerPatternConverter(formattingInfo);
        pc.setOption(option);

        //LogLog.debug("CATEGORY converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 'C':
        pc = new ClassNamePatternConverter(formattingInfo);
        pc.setOption(option);

        //LogLog.debug("CLASS_NAME converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 'd':

        String dateFormatStr = AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT;

        //DateFormat df;
        if (option != null) {
          dateFormatStr = option;
        }

        if (
          dateFormatStr.equalsIgnoreCase(
              AbsoluteTimeDateFormat.ISO8601_DATE_FORMAT)) {
          option = "yyyy-mm-dd HH:mm:ss,SSS";
          //System.out.println("optin is " + option);
        } else if (
          dateFormatStr.equalsIgnoreCase(
              AbsoluteTimeDateFormat.ABS_TIME_DATE_FORMAT)) {
          option = "HH:mm:ss,SSS";
        } else if (
          dateFormatStr.equalsIgnoreCase(
              AbsoluteTimeDateFormat.DATE_AND_TIME_DATE_FORMAT)) {
          option = "dd MMM yyyy HH:mm:ss,SSS";
        }

        pc = new DatePatternConverter(formattingInfo);
        pc.setOption(option);

        //LogLog.debug("DATE converter {"+dateFormatStr+"}.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 'F':
        pc = new FileLocationPatternConverter(formattingInfo);

        //LogLog.debug("File name converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 'l':
        pc = new FullLocationPatternConverter(formattingInfo);

        //LogLog.debug("Location converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 'L':
        pc = new LineLocationPatternConverter(formattingInfo);

        //LogLog.debug("LINE NUMBER converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 'm':
        pc = new MessagePatternConverter(formattingInfo);

        //LogLog.debug("MESSAGE converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 'M':
        pc = new MethodLocationPatternConverter(formattingInfo);

        //LogLog.debug("METHOD converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 'p':
        pc = new LevelPatternConverter(formattingInfo);

        //LogLog.debug("LEVEL converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 'r':
        pc = new RelativeTimePatternConverter(formattingInfo);

        //LogLog.debug("RELATIVE time converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      case 't':
        pc = new ThreadPatternConverter(formattingInfo);

        //LogLog.debug("THREAD converter.");
        //formattingInfo.dump();
        currentLiteral.setLength(0);

        break;

      /*case 'u':
      if(i < patternLength) {
        char cNext = pattern.charAt(i);
        if(cNext >= '0' && cNext <= '9') {
          pc = new UserFieldPatternConverter(formattingInfo, cNext - '0');
          LogLog.debug("USER converter ["+cNext+"].");
          formattingInfo.dump();
          currentLiteral.setLength(0);
          i++;
        }
        else
          LogLog.error("Unexpected char" +cNext+" at position "+i);
      }
      break;*/
      case 'x':
        pc = new NDCPatternConverter(formattingInfo);

        //LogLog.debug("NDC converter.");
        currentLiteral.setLength(0);

        break;

      case 'X':

        //String xOpt = extractOption(); // extractOption returns null if no argument is supplied 
        pc = new MDCPatternConverter(formattingInfo);
        pc.setOption(option);
        currentLiteral.setLength(0);

        break;

      default:
        LogLog.error(
          "Unexpected char [" + c + "] at position " + i
          + " in conversion patterrn.");
        pc = new LiteralPatternConverter(currentLiteral.toString());
        currentLiteral.setLength(0);
      }
    }

    addConverter(pc);
  }

  protected void addConverter(PatternConverter pc) {
    currentLiteral.setLength(0);

    // Add the pattern converter to the list.
    addToList(pc);

    // Next pattern is assumed to be a literal.
    state = LITERAL_STATE;

    // Reset formatting info
    formattingInfo.reset();
  }

  public Hashtable getConverterRegistry() {
    return converterRegistry;
  }

  public void setConverterRegistry(Hashtable hashtable) {
    converterRegistry = hashtable;
  }
}
