/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.log4j.spi;

import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.apache.log4j.chainsaw.logevents.ChainsawLoggingEvent;
import org.apache.log4j.rule.InFixToPostFix;

/**
 * A singleton helper utility which accepts a field name
 * and a LoggingEvent and returns the value of that field.
 *
 * This class defines a grammar used in creation of an expression-based Rule.
 *
 * The only available method is
 * Object getField(String fieldName, LoggingEvent event).
 *
 * Here is a description of the mapping of field names in the grammar
 * to fields on the logging event.  While the getField method returns an Object,
 * the individual types returned per field are described here:
 *
 * Field Name    Field value (String representation        Return type
 * LOGGER        category name (logger)                    String
 * LEVEL         level                                     Level
 * CLASS         locationInformation's class name          String
 * FILE          locationInformation's file name           String
 * LINE          locationInformation's line number         String
 * METHOD        locationInformation's method name         String
 * MSG           message                                   Object
 * NDC           NDC                                       String
 * EXCEPTION     throwable string representation           ThrowableInformation
 * TIMESTAMP     timestamp                                 Long
 * THREAD        thread                                    String
 * PROP.keyName  entry in the Property hashtable           String
 *               mapped to the key [keyName]
 *
 * NOTE:  the values for the 'keyName' portion of the MDC and PROP mappings must
 * be an exact match to the key in the hashTable (case sensitive).
 *
 * If the passed-in field is null or doesn't match an entry
 * in the above-described mapping, an exception is thrown.
 *
 * @author Scott Deboy (sdeboy@apache.org)
 * @author Paul Smith (psmith@apache.org)
 *
 */
public final class LoggingEventFieldResolver {
    /**
     * Keyword list.
     */
    public static final List<String> KEYWORD_LIST = new ArrayList<>();
    /**
     * LOGGER string literal.
     */
    public static final String LOGGER_FIELD = "LOGGER";
    /**
     * LEVEL string literal.
     */
    public static final String LEVEL_FIELD = "LEVEL";
    /**
     * CLASS string literal.
     */
    public static final String CLASS_FIELD = "CLASS";
    /**
     * FILE string literal.
     */
    public static final String FILE_FIELD = "FILE";
    /**
     * LINE string literal.
     */
    public static final String LINE_FIELD = "LINE";
    /**
     * METHOD string literal.
     */
    public static final String METHOD_FIELD = "METHOD";
    /**
     * MSG string literal.
     */
    public static final String MSG_FIELD = "MSG";
    /**
     * NDC string literal.
     */
    public static final String NDC_FIELD = "NDC";
    /**
     * EXCEPTION string literal.
     */
    public static final String EXCEPTION_FIELD = "EXCEPTION";
    /**
     * TIMESTAMP string literal.
     */
    public static final String TIMESTAMP_FIELD = "TIMESTAMP";
    /**
     * THREAD string literal.
     */
    public static final String THREAD_FIELD = "THREAD";
    /**
     * PROP. string literal.
     */
    public static final String PROP_FIELD = "PROP.";
    /**
     * empty string literal.
     */
    public static final String EMPTY_STRING = "";
    /**
     * LOGGER string literal.
     */
    private static final LoggingEventFieldResolver RESOLVER = new LoggingEventFieldResolver();

    /**
     * Create new instance.
     */
    private LoggingEventFieldResolver() {
        super();
        KEYWORD_LIST.add(LOGGER_FIELD);
        KEYWORD_LIST.add(LEVEL_FIELD);
        KEYWORD_LIST.add(CLASS_FIELD);
        KEYWORD_LIST.add(FILE_FIELD);
        KEYWORD_LIST.add(LINE_FIELD);
        KEYWORD_LIST.add(METHOD_FIELD);
        KEYWORD_LIST.add(MSG_FIELD);
        KEYWORD_LIST.add(NDC_FIELD);
        KEYWORD_LIST.add(EXCEPTION_FIELD);
        KEYWORD_LIST.add(TIMESTAMP_FIELD);
        KEYWORD_LIST.add(THREAD_FIELD);
        KEYWORD_LIST.add(PROP_FIELD);
    }

    /**
     * Apply fields.
     * @param replaceText replacement text.
     * @param event logging event.
     * @return evaluted expression
     */
    public String applyFields(final String replaceText, final ChainsawLoggingEvent event) {
        if (replaceText == null) {
            return null;
        }
        InFixToPostFix.CustomTokenizer tokenizer = new InFixToPostFix.CustomTokenizer(replaceText);
        StringBuffer result = new StringBuffer();
        boolean found = false;

        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            if (isField(token) || token.toUpperCase(Locale.US).startsWith(PROP_FIELD)) {
                result.append(getValue(token, event).toString());
                found = true;
            } else {
                result.append(token);
            }
        }
        if (found) {
            return result.toString();
        }
        return null;
    }

    /**
     * Get singleton instance.
     * @return singleton instance
     */
    public static LoggingEventFieldResolver getInstance() {
        return RESOLVER;
    }

    /**
     * Determines if specified string is a recognized field.
     * @param fieldName field name
     * @return true if recognized field.
     */
    public boolean isField(final String fieldName) {
        if (fieldName != null) {
            return (KEYWORD_LIST.contains(fieldName.toUpperCase(Locale.US))
                    || fieldName.toUpperCase().startsWith(PROP_FIELD));
        }
        return false;
    }

    /**
     * Get value of field.
     * @param fieldName field
     * @param event event
     * @return value of field
     */
    public Object getValue(final String fieldName, final ChainsawLoggingEvent event) {
        String upperField = fieldName.toUpperCase(Locale.US);
        if (LOGGER_FIELD.equals(upperField)) {
            return event.m_logger;
        } else if (LEVEL_FIELD.equals(upperField)) {
            return event.m_level;
        } else if (MSG_FIELD.equals(upperField)) {
            return event.m_message;
        } else if (NDC_FIELD.equals(upperField)) {
            String ndcValue = event.m_ndc;
            return ((ndcValue == null) ? EMPTY_STRING : ndcValue);
        } else if (EXCEPTION_FIELD.equals(upperField)) {
            //        String[] throwableRep = event.getThrowableStrRep();
            //        if (throwableRep == null) {
            //            return EMPTY_STRING;
            //        } else {
            //            return getExceptionMessage(throwableRep);
            //        }
            return "";
        } else if (TIMESTAMP_FIELD.equals(upperField)) {
            return event.m_timestamp;
        } else if (THREAD_FIELD.equals(upperField)) {
            return event.m_threadName;
        } else if (upperField.startsWith(PROP_FIELD)) {
            // note: need to use actual fieldname since case matters
            String realFieldName = fieldName.substring(5);
            String property = event.getProperty(realFieldName);
            if (property != null && property.length() >= 1) {
                return property;
            }

            // We did not get the property in a case-sensitive manner - check for
            // case-insensitive
            for (Map.Entry<String, String> entry : event.getProperties().entrySet()) {
                if (entry.getKey().equalsIgnoreCase(realFieldName)) {
                    return entry.getValue();
                }
            }

            return EMPTY_STRING;
        } else {
            org.apache.log4j.chainsaw.logevents.LocationInfo info = event.m_locationInfo;
            if (CLASS_FIELD.equals(upperField)) {
                return ((info == null) ? EMPTY_STRING : info.className);
            } else if (FILE_FIELD.equals(upperField)) {
                return ((info == null) ? EMPTY_STRING : info.fileName);
            } else if (LINE_FIELD.equals(upperField)) {
                return ((info == null) ? EMPTY_STRING : info.lineNumber);
            } else if (METHOD_FIELD.equals(upperField)) {
                return ((info == null) ? EMPTY_STRING : info.methodName);
            }
        }

        // there wasn't a match, so throw a runtime exception
        throw new IllegalArgumentException("Unsupported field name: " + fieldName);
    }

    /**
     * Get message from throwable representation.
     * @param exception exception
     * @return message
     */
    private static String getExceptionMessage(final String[] exception) {
        StringBuffer buff = new StringBuffer();
        for (int i = 0; i < exception.length; i++) {
            buff.append(exception[i]);
        }
        return buff.toString();
    }
}
