/*
 * 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 flex.messaging.log;

import flex.messaging.config.ConfigMap;
import flex.messaging.util.ExceptionUtil;
import flex.messaging.util.StringUtils;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 *
 */
public class LineFormattedTarget extends AbstractTarget
{
    /**
     * Indicates if the date should be added to the trace.
     */
    protected boolean includeDate;

    /**
     * Indicates if the time should be added to the trace.
     */
    protected boolean includeTime;

    /**
     * Indicates if the level for the event should added to the trace.
     */
    protected boolean includeLevel;

    /**
     * Indicates if the category for this target should added to the trace.
     */
    protected boolean includeCategory;

    /**
     * A prefix to prepend onto each logged message.
     */
    protected String prefix = null;

    /**
     * The formatter to write the date as part of the logging statement.
     * Defaults to MM/dd/yyyy format.
     */
    protected DateFormat dateFormater = new SimpleDateFormat("MM/dd/yyyy");

    /**
     * The formatter to write the time as part of the logging statement.
     * Defaults to HH:mm:ss.SSS format.
     */
    protected DateFormat timeFormatter = new SimpleDateFormat("HH:mm:ss.SSS");

    //--------------------------------------------------------------------------
    //
    // Constructor
    //
    //--------------------------------------------------------------------------

    /**
     * Default constructor.
     */
    public LineFormattedTarget()
    {
        super();
    }

    //--------------------------------------------------------------------------
    //
    // Initialize, validate, start, and stop methods.
    //
    //--------------------------------------------------------------------------

    /**
     * Initializes the target with id and properties. Subclasses can overwrite.
     *
     * @param id id for the target which is ignored.
     * @param properties ConfigMap of properties for the target.
     */
    public void initialize(String id, ConfigMap properties)
    {
        super.initialize(id, properties);

        includeTime = properties.getPropertyAsBoolean("includeTime", false);
        includeDate = properties.getPropertyAsBoolean("includeDate", false);
        includeCategory = properties.getPropertyAsBoolean("includeCategory", false);
        includeLevel = properties.getPropertyAsBoolean("includeLevel", false);
        prefix = properties.getPropertyAsString("prefix", null);
    }

    //--------------------------------------------------------------------------
    //
    // Public Getters and Setters for AbstractService properties
    //
    //--------------------------------------------------------------------------

    /**
     * Returns includeCategory property.
     *
     * @return <code>true</code> if category is included; <code>false</code> otherwise.
     */
    public boolean isIncludeCategory()
    {
        return includeCategory;
    }

    /**
     * Sets includeCategory property.
     *
     * @param includeCategory the include category
     */
    public void setIncludeCategory(boolean includeCategory)
    {
        this.includeCategory = includeCategory;
    }

    /**
     * Returns includeDate property.
     *
     * @return <code>true</code> if date is included; <code>false</code> otherwise.
     */
    public boolean isIncludeDate()
    {
        return includeDate;
    }

    /**
     * Sets includeDate property.
     *
     * @param includeDate the include date 
     */
    public void setIncludeDate(boolean includeDate)
    {
        this.includeDate = includeDate;
    }

    /**
     * Returns includeLevel property.
     *
     * @return <code>true</code> if level is included; <code>false</code> otherwise.
     */
    public boolean isIncludeLevel()
    {
        return includeLevel;
    }

    /**
     * Sets includeLevel property.
     *
     * @param includeLevel the include level
     */
    public void setIncludeLevel(boolean includeLevel)
    {
        this.includeLevel = includeLevel;
    }

    /**
     * Returns includeTime property.
     *
     * @return <code>true</code> if time is included; <code>false</code> otherwise.
     */
    public boolean isIncludeTime()
    {
        return includeTime;
    }

    /**
     * Sets includeTime property.
     *
     * @param includeTime the include time
     */
    public void setIncludeTime(boolean includeTime)
    {
        this.includeTime = includeTime;
    }

    /**
     * Returns prefix property.
     *
     * @return The prefix for log messages.
     */
    public String getPrefix()
    {
        return prefix;
    }

    /**
     * Sets prefix property.
     *
     * @param prefix the prefix string
     */
    public void setPrefix(String prefix)
    {
        this.prefix = prefix;
    }

    /**
     * This method handles a <code>LogEvent</code> from an associated logger.
     * A target uses this method to translate the event into the appropriate
     * format for transmission, storage, or display.
     * This method will be called only if the event's level is in range of the
     * target's level.
     * @param event the log event
     */
    public void logEvent(LogEvent event)
    {
        String pre = "";
        if (prefix != null)
        {
            pre = prefix + " "; // any space is stripped from config
        }

        String date = "";
        if (includeDate || includeTime)
        {
            StringBuffer buffer = new StringBuffer();
            Date d = new Date();
            if (includeDate)
            {
                buffer.append(dateFormater.format(d));
                buffer.append(" ");
            }
            if (includeTime)
            {
                buffer.append(timeFormatter.format(d));
                buffer.append(" ");
            }
            date = buffer.toString();
        }

        String cat = includeCategory ?
                           ("[" + event.logger.getCategory() + "] ") : "";
        String level = "";
        if (includeLevel)
        {
            StringBuffer buffer = new StringBuffer();
            buffer.append("[");
            buffer.append(LogEvent.getLevelString(event.level));
            buffer.append("]");
            buffer.append(" ");
            level = buffer.toString();
        }
        StringBuffer result = new StringBuffer(pre);
        result.append(date).append(level).append(cat).append(event.message);

        if (event.throwable != null)
            result.append(StringUtils.NEWLINE).append(ExceptionUtil.toString(event.throwable));

        internalLog(result.toString());
    }

    //--------------------------------------------------------------------------
    //
    // Protected/private methods.
    //
    //--------------------------------------------------------------------------

    /**
     * Descendants of this class should override this method to direct the
     * specified message to the desired output.
     *
     * @param  message String containing preprocessed log message which may
     * include time, date, category, etc. based on property settings,
     * such as <code>includeDate</code>, <code>includeCategory</code>,
     * etc.
     */
    protected void internalLog(String message)
    {
        // override this method to perform the redirection to the desired output
    }
}
