/*
 * 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.Logger;
import org.apache.logging.log4j.core.Core;
import org.apache.logging.log4j.core.appender.db.ColumnMapping;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.layout.PatternLayout;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.plugins.PluginFactory;
import org.apache.logging.log4j.plugins.validation.constraints.Required;
import org.apache.logging.log4j.status.StatusLogger;
import org.apache.logging.log4j.util.Strings;

/**
 * A configuration element used to configure which event properties are logged to which columns in the database table.
 *
 * @see ColumnMapping
 */
@Plugin(name = "Column", category = Core.CATEGORY_NAME, printObject = true)
public final class ColumnConfig {
    public static class Builder implements org.apache.logging.log4j.plugins.util.Builder<ColumnConfig> {

        @PluginConfiguration
        private Configuration configuration;

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

        @PluginBuilderAttribute
        private String pattern;

        @PluginBuilderAttribute
        private String literal;

        @PluginBuilderAttribute
        private boolean isEventTimestamp;

        @PluginBuilderAttribute
        private boolean isUnicode = true;

        @PluginBuilderAttribute
        private boolean isClob;

        @Override
        public ColumnConfig build() {
            if (Strings.isEmpty(name)) {
                LOGGER.error("The column config is not valid because it does not contain a column name.");
                return null;
            }

            final boolean isPattern = Strings.isNotEmpty(pattern);
            final boolean isLiteralValue = Strings.isNotEmpty(literal);

            if ((isPattern && isLiteralValue) || (isPattern && isEventTimestamp) || (isLiteralValue && isEventTimestamp)) {
                LOGGER.error("The pattern, literal, and isEventTimestamp attributes are mutually exclusive.");
                return null;
            }

            if (isEventTimestamp) {
                return new ColumnConfig(name, null, null, true, false, false);
            }

            if (isLiteralValue) {
                return new ColumnConfig(name, null, literal, false, false, false);
            }

            if (isPattern) {
                final PatternLayout layout =
                    PatternLayout.newBuilder()
                        .setPattern(pattern)
                        .setConfiguration(configuration)
                        .setAlwaysWriteExceptions(false)
                        .build();
                return new ColumnConfig(name, layout, null, false, isUnicode, isClob);
            }

            LOGGER.error("To configure a column you must specify a pattern or literal or set isEventDate to true.");
            return null;
        }

        /**
         * If {@code "true"}, indicates that the column is a character LOB (CLOB).
         *
         * @return this.
         */
        public Builder setClob(final boolean clob) {
            isClob = clob;
            return this;
        }

        /**
         * The configuration object.
         *
         * @return this.
         */
        public Builder setConfiguration(final Configuration configuration) {
            this.configuration = configuration;
            return this;
        }

        /**
         * If {@code "true"}, indicates that this column is a date-time column in which the event timestamp should be
         * inserted. Mutually exclusive with {@code pattern!=null} and {@code literal!=null}.
         *
         * @return this.
         */
        public Builder setEventTimestamp(final boolean eventTimestamp) {
            isEventTimestamp = eventTimestamp;
            return this;
        }

        /**
         * The literal value to insert into the column as-is without any quoting or escaping. Mutually exclusive with
         * {@code pattern!=null} and {@code eventTimestamp=true}.
         *
         * @return this.
         */
        public Builder setLiteral(final String literal) {
            this.literal = literal;
            return this;
        }

        /**
         * The name of the database column as it exists within the database table.
         *
         * @return this.
         */
        public Builder setName(final String name) {
            this.name = name;
            return this;
        }

        /**
         * The {@link PatternLayout} pattern to insert in this column. Mutually exclusive with
         * {@code literal!=null} and {@code eventTimestamp=true}
         *
         * @return this.
         */
        public Builder setPattern(final String pattern) {
            this.pattern = pattern;
            return this;
        }

        /**
         * If {@code "true"}, indicates that the column is a Unicode String.
         *
         * @return this.
         */
        public Builder setUnicode(final boolean unicode) {
            isUnicode = unicode;
            return this;
        }
    }

    private static final Logger LOGGER = StatusLogger.getLogger();
    @PluginFactory
    public static Builder newBuilder() {
        return new Builder();
    }
    private final String columnName;
    private final String columnNameKey;
    private final PatternLayout layout;
    private final String literalValue;

    private final boolean eventTimestamp;

    private final boolean unicode;

    private final boolean clob;

    private ColumnConfig(final String columnName, final PatternLayout layout, final String literalValue,
                         final boolean eventDate, final boolean unicode, final boolean clob) {
        this.columnName = columnName;
        this.columnNameKey = ColumnMapping.toKey(columnName);
        this.layout = layout;
        this.literalValue = literalValue;
        this.eventTimestamp = eventDate;
        this.unicode = unicode;
        this.clob = clob;
    }

    public String getColumnName() {
        return this.columnName;
    }

    public String getColumnNameKey() {
        return this.columnNameKey;
    }

    public PatternLayout getLayout() {
        return this.layout;
    }

    public String getLiteralValue() {
        return this.literalValue;
    }

    public boolean isClob() {
        return this.clob;
    }

    public boolean isEventTimestamp() {
        return this.eventTimestamp;
    }

    public boolean isUnicode() {
        return this.unicode;
    }

    @Override
    public String toString() {
        return "{ name=" + this.columnName + ", layout=" + this.layout + ", literal=" + this.literalValue
                + ", timestamp=" + this.eventTimestamp + " }";
    }
}
