/*
 * 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.logging.log4j.jpa.appender;

import java.util.Map;
import javax.persistence.Basic;
import javax.persistence.Convert;
import javax.persistence.MappedSuperclass;
import javax.persistence.Transient;

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.ThreadContext;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.impl.ThrowableProxy;
import org.apache.logging.log4j.core.time.Instant;
import org.apache.logging.log4j.jpa.converter.*;
import org.apache.logging.log4j.message.Message;

/**
 * Users of the JPA appender may want to extend this class instead of {@link AbstractLogEventWrapperEntity}. This class
 * implements all of the required mutator methods but does not implement a mutable entity ID property. In order to
 * create an entity based on this class, you need only create two constructors matching this class's constructors,
 * annotate the class {@link javax.persistence.Entity @Entity} and {@link javax.persistence.Table @Table}, and implement
 * the fully mutable entity ID property annotated with {@link javax.persistence.Id @Id} and
 * {@link javax.persistence.GeneratedValue @GeneratedValue} to tell the JPA provider how to calculate an ID for new
 * events.<br>
 * <br>
 * The attributes in this entity use the default column names (which, according to the JPA spec, are the property names
 * minus the "get" and "set" from the accessors/mutators). If you want to use different column names for one or more
 * columns, override the necessary accessor methods defined in this class with the same annotations plus the
 * {@link javax.persistence.Column @Column} annotation to specify the column name.<br>
 * <br>
 * The #getContextMap() and {@link #getContextStack()} attributes in this entity use the
 * {@link ContextMapAttributeConverter} and {@link ContextStackAttributeConverter}, respectively. These convert the
 * properties to simple strings that cannot be converted back to the properties. If you wish to instead convert these to
 * a reversible JSON string, override these attributes with the same annotations but use the
 * {@link org.apache.logging.log4j.jpa.converter.ContextMapJsonAttributeConverter} and
 * {@link org.apache.logging.log4j.jpa.converter.ContextStackJsonAttributeConverter} instead.<br>
 * <br>
 * All other attributes in this entity use reversible converters that can be used for both persistence and retrieval. If
 * there are any attributes you do not want persistent, you should override their accessor methods and annotate with
 * {@link javax.persistence.Transient @Transient}.
 *
 * @see AbstractLogEventWrapperEntity
 */
@MappedSuperclass
public abstract class BasicLogEventEntity extends AbstractLogEventWrapperEntity {
    private static final long serialVersionUID = 1L;

    /**
     * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
     * signature. The no-argument constructor is required for a standards-compliant JPA provider to accept this as an
     * entity.
     */
    public BasicLogEventEntity() {
        super();
    }

    /**
     * Instantiates this base class. All concrete implementations must have a constructor matching this constructor's
     * signature. This constructor is used for wrapping this entity around a logged event.
     *
     * @param wrappedEvent The underlying event from which information is obtained.
     */
    public BasicLogEventEntity(final LogEvent wrappedEvent) {
        super(wrappedEvent);
    }

    /**
     * Gets the level. Annotated with {@code @Basic} and {@code @Enumerated(EnumType.STRING)}.
     *
     * @return the level.
     */
    @Override
    @Convert(converter = LevelAttributeConverter.class)
    public Level getLevel() {
        return this.getWrappedEvent().getLevel();
    }

    /**
     * Gets the logger name. Annotated with {@code @Basic}.
     *
     * @return the logger name.
     */
    @Override
    @Basic
    public String getLoggerName() {
        return this.getWrappedEvent().getLoggerName();
    }

    /**
     * Gets the source location information. Annotated with
     * {@code @Convert(converter = StackTraceElementAttributeConverter.class)}.
     *
     * @return the source location information.
     * @see StackTraceElementAttributeConverter
     */
    @Override
    @Convert(converter = StackTraceElementAttributeConverter.class)
    public StackTraceElement getSource() {
        return this.getWrappedEvent().getSource();
    }

    /**
     * Gets the message. Annotated with {@code @Convert(converter = MessageAttributeConverter.class)}.
     *
     * @return the message.
     * @see MessageAttributeConverter
     */
    @Override
    @Convert(converter = MessageAttributeConverter.class)
    public Message getMessage() {
        return this.getWrappedEvent().getMessage();
    }

    /**
     * Gets the marker. Annotated with {@code @Convert(converter = MarkerAttributeConverter.class)}.
     *
     * @return the marker.
     * @see MarkerAttributeConverter
     */
    @Override
    @Convert(converter = MarkerAttributeConverter.class)
    public Marker getMarker() {
        return this.getWrappedEvent().getMarker();
    }

    /**
     * Gets the thread ID. Annotated with {@code @Basic}.
     *
     * @return the thread ID.
     */
    @Override
    @Basic
    public long getThreadId() {
        return this.getWrappedEvent().getThreadId();
    }

    /**
     * Gets the thread name. Annotated with {@code @Basic}.
     *
     * @return the thread name.
     */
    @Override
    @Basic
    public int getThreadPriority() {
        return this.getWrappedEvent().getThreadPriority();
    }

    /**
     * Gets the thread name. Annotated with {@code @Basic}.
     *
     * @return the thread name.
     */
    @Override
    @Basic
    public String getThreadName() {
        return this.getWrappedEvent().getThreadName();
    }

    /**
     * Gets the number of milliseconds since JVM launch. Annotated with {@code @Basic}.
     *
     * @return the number of milliseconds since JVM launch.
     */
    @Override
    @Basic
    public long getTimeMillis() {
        return this.getWrappedEvent().getTimeMillis();
    }

    @Override
    @Convert(converter = InstantAttributeConverter.class)
    public Instant getInstant() {
        return this.getWrappedEvent().getInstant();
    }

    /**
     * Returns the value of the running Java Virtual Machine's high-resolution time source when this event was created,
     * or a dummy value if it is known that this value will not be used downstream.
     *
     * @return the JVM nano time
     */
    @Override
    @Basic
    public long getNanoTime() {
        return this.getWrappedEvent().getNanoTime();
    }

    /**
     * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}.
     *
     * @return the exception logged.
     * @see ThrowableAttributeConverter
     */
    @Override
    @Convert(converter = ThrowableAttributeConverter.class)
    public Throwable getThrown() {
        return this.getWrappedEvent().getThrown();
    }

    /**
     * Gets the exception logged. Annotated with {@code @Convert(converter = ThrowableAttributeConverter.class)}.
     *
     * @return the exception logged.
     * @see ThrowableAttributeConverter
     */
    @Override
    @Transient
    public ThrowableProxy getThrownProxy() {
        return this.getWrappedEvent().getThrownProxy();
    }

    /**
     * Gets the context stack. Annotated with {@code @Convert(converter = ContextStackAttributeConverter.class)}.
     *
     * @return the context stack.
     * @see ContextStackAttributeConverter
     * @see org.apache.logging.log4j.jpa.converter.ContextStackJsonAttributeConverter
     */
    @Override
    @Convert(converter = ContextStackAttributeConverter.class)
    public ThreadContext.ContextStack getContextStack() {
        return this.getWrappedEvent().getContextStack();
    }

    /**
     * Gets the fully qualified class name of the caller of the logger API. Annotated with {@code @Basic}.
     *
     * @return the fully qualified class name of the caller of the logger API.
     */
    @Override
    @Basic
    public String getLoggerFqcn() {
        return this.getWrappedEvent().getLoggerFqcn();
    }
}
