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

import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.Filter;
import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.appender.AbstractAppender;
import org.apache.logging.log4j.core.appender.db.AbstractDatabaseAppender;
import org.apache.logging.log4j.core.appender.db.ColumnMapping;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.plugins.PluginElement;
import org.apache.logging.log4j.plugins.PluginFactory;
import org.apache.logging.log4j.plugins.convert.TypeConverter;
import org.apache.logging.log4j.plugins.validation.constraints.Required;
import org.apache.logging.log4j.util.Assert;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.util.Arrays;

/**
 * This Appender writes logging events to a relational database using standard JDBC mechanisms. It takes a list of
 * {@link ColumnConfig}s and/or {@link ColumnMapping}s with which it determines how to save the event data into the
 * appropriate columns in the table. ColumnMapping is new as of Log4j 2.8 and supports
 * {@linkplain TypeConverter type conversion} and persistence using {@link PreparedStatement#setObject(int, Object)}.
 * A {@link ConnectionSource} plugin instance instructs the appender (and {@link JdbcDatabaseManager}) how to connect to
 * the database. This appender can be reconfigured at run time.
 *
 * @see ColumnConfig
 * @see ColumnMapping
 * @see ConnectionSource
 */
@Plugin(name = "JDBC", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE, printObject = true)
public final class JdbcAppender extends AbstractDatabaseAppender<JdbcDatabaseManager> {

    public static class Builder<B extends Builder<B>> extends AbstractAppender.Builder<B>
        implements org.apache.logging.log4j.plugins.util.Builder<JdbcAppender> {

        @PluginElement("ConnectionSource")
        @Required(message = "No ConnectionSource provided")
        private ConnectionSource connectionSource;

        @PluginBuilderAttribute
        private boolean immediateFail;

        @PluginBuilderAttribute
        private int bufferSize;

        @PluginBuilderAttribute
        @Required(message = "No table name provided")
        private String tableName;

        @PluginElement("ColumnConfigs")
        private ColumnConfig[] columnConfigs;

        @PluginElement("ColumnMappings")
        private ColumnMapping[] columnMappings;

        @PluginBuilderAttribute
        private boolean truncateStrings = true;

        // TODO Consider moving up to AbstractDatabaseAppender.Builder.
        @PluginBuilderAttribute
        private long reconnectIntervalMillis = DEFAULT_RECONNECT_INTERVAL_MILLIS;

        @Override
        public JdbcAppender build() {
            if (Assert.isEmpty(columnConfigs) && Assert.isEmpty(columnMappings)) {
                LOGGER.error("Cannot create JdbcAppender without any columns.");
                return null;
            }
            final String managerName = "JdbcManager{name=" + getName() + ", bufferSize=" + bufferSize + ", tableName="
                    + tableName + ", columnConfigs=" + Arrays.toString(columnConfigs) + ", columnMappings="
                    + Arrays.toString(columnMappings) + '}';
            final JdbcDatabaseManager manager = JdbcDatabaseManager.getManager(managerName, bufferSize, getLayout(),
                    connectionSource, tableName, columnConfigs, columnMappings, immediateFail, reconnectIntervalMillis,
                    truncateStrings);
            if (manager == null) {
                return null;
            }
            return new JdbcAppender(getName(), getFilter(), getLayout(), isIgnoreExceptions(), getPropertyArray(),
                    manager);
        }

        public long getReconnectIntervalMillis() {
            return reconnectIntervalMillis;
        }

        public boolean isImmediateFail() {
            return immediateFail;
        }

        /**
         * If an integer greater than 0, this causes the appender to buffer log events and flush whenever the buffer
         * reaches this size.
         *
         * @param bufferSize buffer size.
         *
         * @return this
         */
        public B setBufferSize(final int bufferSize) {
            this.bufferSize = bufferSize;
            return asBuilder();
        }

        /**
         * Information about the columns that log event data should be inserted into and how to insert that data.
         *
         * @param columnConfigs Column configurations.
         *
         * @return this
         */
        public B setColumnConfigs(final ColumnConfig... columnConfigs) {
            this.columnConfigs = columnConfigs;
            return asBuilder();
        }

        public B setColumnMappings(final ColumnMapping... columnMappings) {
            this.columnMappings = columnMappings;
            return asBuilder();
        }

        /**
         * The connections source from which database connections should be retrieved.
         *
         * @param connectionSource The connections source.
         *
         * @return this
         */
        public B setConnectionSource(final ConnectionSource connectionSource) {
            this.connectionSource = connectionSource;
            return asBuilder();
        }

        public void setImmediateFail(final boolean immediateFail) {
            this.immediateFail = immediateFail;
        }

        public void setReconnectIntervalMillis(final long reconnectIntervalMillis) {
            this.reconnectIntervalMillis = reconnectIntervalMillis;
        }

        /**
         * The name of the database table to insert log events into.
         *
         * @param tableName The database table name.
         *
         * @return this
         */
        public B setTableName(final String tableName) {
            this.tableName = tableName;
            return asBuilder();
        }

        public B setTruncateStrings(final boolean truncateStrings) {
            this.truncateStrings = truncateStrings;
            return asBuilder();
        }

    }

    @PluginFactory
    public static <B extends Builder<B>> B newBuilder() {
        return new Builder<B>().asBuilder();
    }

    private final String description;

    private JdbcAppender(final String name, final Filter filter, final Layout<? extends Serializable> layout,
            final boolean ignoreExceptions, Property[] properties, final JdbcDatabaseManager manager) {
        super(name, filter, layout, ignoreExceptions, properties, manager);
        this.description = this.getName() + "{ manager=" + this.getManager() + " }";
    }

    @Override
    public String toString() {
        return this.description;
    }
}
