/*
 * 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.bridge;

import java.lang.reflect.Method;

import org.apache.log4j.Category;
import org.apache.log4j.Level;
import org.apache.log4j.spi.LocationInfo;
import org.apache.log4j.spi.LoggingEvent;
import org.apache.log4j.spi.ThrowableInformation;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.util.Loader;
import org.apache.logging.log4j.core.util.Throwables;
import org.apache.logging.log4j.spi.StandardLevel;
import org.apache.logging.log4j.status.StatusLogger;

/**
 * Converts a Log4j 2 LogEvent into the components needed by a Log4j 1.x LoggingEvent.
 * This class requires Log4j 2.
 */
public class LogEventAdapter extends LoggingEvent {

    private static final long JVM_START_TIME = initStartTime();

    private final LogEvent event;

    public LogEventAdapter(LogEvent event) {
        this.event = event;
    }

    public LogEvent getEvent() {
        return this.event;
    }

    /**
     Set the location information for this logging event. The collected
     information is cached for future use.
     */
    @Override
    public LocationInfo getLocationInformation() {
        return new LocationInfo(event.getSource());
    }

    /**
     * Return the level of this event. Use this form instead of directly
     * accessing the <code>level</code> field.  */
    @Override
    public Level getLevel() {
        switch (StandardLevel.getStandardLevel(event.getLevel().intLevel())) {
            case TRACE:
                return Level.TRACE;
            case DEBUG:
                return Level.DEBUG;
            case INFO:
                return Level.INFO;
            case WARN:
                return Level.WARN;
            case ERROR:
                return Level.ERROR;
            case FATAL:
                return Level.FATAL;
            case OFF:
                return Level.OFF;
            case ALL:
                return Level.ALL;
            default:
                return Level.ERROR;
        }
    }

    /**
     * Return the name of the logger. Use this form instead of directly
     * accessing the <code>categoryName</code> field.
     */
    @Override
    public String getLoggerName() {
        return event.getLoggerName();
    }

    /**
     * Gets the logger of the event.
     */
    @Override
    public Category getLogger() {
        return Category.getInstance(event.getLoggerName());
    }

    /*
     Return the message for this logging event.
    */
    @Override
    public
    Object getMessage() {
        return event.getMessage().getFormattedMessage();
    }

    /*
     * This method returns the NDC for this event.
     */
    @Override
    public
    String getNDC() {
        return event.getContextStack().toString();
    }


    /*
     Returns the the context corresponding to the <code>key</code> parameter.
     */
    @Override
    public
    Object getMDC(String key) {
        if (event.getContextData() != null) {
            return event.getContextData().getValue(key);
        } else {
            return null;
        }
    }

    /**
     Obtain a copy of this thread's MDC prior to serialization or
     asynchronous logging.
     */
    @Override
    public
    void getMDCCopy() {
    }

    @Override
    public
    String getRenderedMessage() {
        return event.getMessage().getFormattedMessage();
    }

    /**
     Returns the time when the application started, in milliseconds
     elapsed since 01.01.1970.  */
    public static long getStartTime() {
        return JVM_START_TIME;
    }

    @Override
    public
    String getThreadName() {
        return event.getThreadName();
    }

    /**
     Returns the throwable information contained within this
     event. May be <code>null</code> if there is no such information.

     <p>Note that the {@link Throwable} object contained within a
     {@link ThrowableInformation} does not survive serialization.

     @since 1.1 */
    @Override
    public
    ThrowableInformation getThrowableInformation() {
        if (event.getThrown() != null) {
            return new ThrowableInformation(event.getThrown());
        }
        return null;
    }

    /**
     Return this event's throwable's string[] representaion.
     */
    @Override
    public
    String[] getThrowableStrRep() {
        if (event.getThrown() != null) {
            return Throwables.toStringList(event.getThrown()).toArray(new String[0]);
        }
        return null;
    }

    /**
     * Returns the result of {@code ManagementFactory.getRuntimeMXBean().getStartTime()},
     * or the current system time if JMX is not available.
     */
    private static long initStartTime() {
        // We'd like to call ManagementFactory.getRuntimeMXBean().getStartTime(),
        // but Google App Engine throws a java.lang.NoClassDefFoundError
        // "java.lang.management.ManagementFactory is a restricted class".
        // The reflection is necessary because without it, Google App Engine
        // will refuse to initialize this class.
        try {
            final Class<?> factoryClass = Loader.loadSystemClass("java.lang.management.ManagementFactory");
            final Method getRuntimeMXBean = factoryClass.getMethod("getRuntimeMXBean");
            final Object runtimeMXBean = getRuntimeMXBean.invoke(null);

            final Class<?> runtimeMXBeanClass = Loader.loadSystemClass("java.lang.management.RuntimeMXBean");
            final Method getStartTime = runtimeMXBeanClass.getMethod("getStartTime");
            return (Long) getStartTime.invoke(runtimeMXBean);
        } catch (final Throwable t) {
            StatusLogger.getLogger().error("Unable to call ManagementFactory.getRuntimeMXBean().getStartTime(), "
                + "using system time for OnStartupTriggeringPolicy", t);
            // We have little option but to declare "now" as the beginning of time.
            return System.currentTimeMillis();
        }
    }
}
