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

import org.apache.log4j.Appender;
import org.apache.log4j.Layout;
import org.apache.log4j.bridge.AppenderWrapper;
import org.apache.log4j.bridge.LayoutAdapter;
import org.apache.log4j.bridge.LayoutWrapper;
import org.apache.log4j.builders.AbstractBuilder;
import org.apache.log4j.builders.Holder;
import org.apache.log4j.config.Log4j1Configuration;
import org.apache.log4j.config.PropertiesConfiguration;
import org.apache.log4j.spi.Filter;
import org.apache.log4j.xml.XmlConfiguration;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.appender.SyslogAppender;
import org.apache.logging.log4j.core.layout.SyslogLayout;
import org.apache.logging.log4j.core.net.Facility;
import org.apache.logging.log4j.core.net.Protocol;
import org.apache.logging.log4j.plugins.Plugin;
import org.apache.logging.log4j.status.StatusLogger;
import org.w3c.dom.Element;

import java.util.Properties;

import static org.apache.log4j.builders.BuilderManager.CATEGORY;
import static org.apache.log4j.config.Log4j1Configuration.THRESHOLD_PARAM;
import static org.apache.log4j.xml.XmlConfiguration.FILTER_TAG;
import static org.apache.log4j.xml.XmlConfiguration.LAYOUT_TAG;
import static org.apache.log4j.xml.XmlConfiguration.NAME_ATTR;
import static org.apache.log4j.xml.XmlConfiguration.PARAM_TAG;
import static org.apache.log4j.xml.XmlConfiguration.VALUE_ATTR;
import static org.apache.log4j.xml.XmlConfiguration.forEachElement;

/**
 * Build a File Appender
 */
@Plugin(name = "org.apache.log4j.net.SyslogAppender", category = CATEGORY)
public class SyslogAppenderBuilder extends AbstractBuilder implements AppenderBuilder {

    private static final Logger LOGGER = StatusLogger.getLogger();
    private static final String FACILITY_PARAM = "Facility";
    private static final String SYSLOG_HOST_PARAM = "SyslogHost";
    private static final int SYSLOG_PORT = 512;

    public SyslogAppenderBuilder() {
    }

    public SyslogAppenderBuilder(String prefix, Properties props) {
        super(prefix, props);
    }

    @Override
    public Appender parseAppender(Element appenderElement, XmlConfiguration config) {
        String name = appenderElement.getAttribute(NAME_ATTR);
        Holder<Layout> layout = new Holder<>();
        Holder<Filter> filter = new Holder<>();
        Holder<String> facility = new Holder<>();
        Holder<String> level = new Holder<>();
        Holder<String> host = new Holder<>();
        forEachElement(appenderElement.getChildNodes(), (currentElement) -> {
            switch (currentElement.getTagName()) {
                case LAYOUT_TAG:
                    layout.set(config.parseLayout(currentElement));
                    break;
                case FILTER_TAG:
                    filter.set(config.parseFilters(currentElement));
                    break;
                case PARAM_TAG: {
                    switch (currentElement.getAttribute(NAME_ATTR)) {
                        case SYSLOG_HOST_PARAM: {
                            host.set(currentElement.getAttribute(VALUE_ATTR));
                            break;
                        }
                        case FACILITY_PARAM:
                            facility.set(currentElement.getAttribute(VALUE_ATTR));
                            break;
                        case THRESHOLD_PARAM: {
                            String value = currentElement.getAttribute(VALUE_ATTR);
                            if (value == null) {
                                LOGGER.warn("No value supplied for Threshold parameter, ignoring.");
                            } else {
                                level.set(value);
                            }
                            break;
                        }
                    }
                    break;
                }
            }
        });

        return createAppender(name, config, layout.get(), facility.get(), filter.get(), host.get(), level.get());
    }


    @Override
    public Appender parseAppender(final String name, final String appenderPrefix, final String layoutPrefix,
            final String filterPrefix, final Properties props, final PropertiesConfiguration configuration) {
        Filter filter = configuration.parseAppenderFilters(props, filterPrefix, name);
        Layout layout = configuration.parseLayout(layoutPrefix, name, props);
        String level = getProperty(THRESHOLD_PARAM);
        String facility = getProperty(FACILITY_PARAM, "LOCAL0");
        String syslogHost = getProperty(SYSLOG_HOST_PARAM, "localhost:514");

        return createAppender(name, configuration, layout, facility, filter, syslogHost, level);
    }

    private Appender createAppender(final String name, final Log4j1Configuration configuration, Layout layout,
            String facility, final Filter filter, final String syslogHost, final String level) {
        Holder<String> host = new Holder<>();
        Holder<Integer> port = new Holder<>();
        resolveSyslogHost(syslogHost, host, port);
        org.apache.logging.log4j.core.Layout appenderLayout;
        if (layout instanceof LayoutWrapper) {
            appenderLayout = ((LayoutWrapper) layout).getLayout();
        } else if (layout != null) {
            appenderLayout = new LayoutAdapter(layout);
        } else {
            appenderLayout = SyslogLayout.newBuilder()
                    .setFacility(Facility.toFacility(facility))
                    .setConfiguration(configuration)
                    .build();
        }

        org.apache.logging.log4j.core.Filter fileFilter = buildFilters(level, filter);
        return new AppenderWrapper(SyslogAppender.newBuilder()
                .setName(name)
                .setConfiguration(configuration)
                .setLayout(appenderLayout)
                .setFilter(fileFilter)
                .setPort(port.get())
                .setProtocol(Protocol.TCP)
                .setHost(host.get())
                .build());
    }

    private void resolveSyslogHost(String syslogHost, Holder<String> host, Holder<Integer> port) {
        int urlPort = -1;

        //
        //  If not an unbracketed IPv6 address then
        //      parse as a URL
        //
        String[] parts = syslogHost.split(":");
        if (parts.length == 1) {
            host.set(parts[0]);
            port.set(SYSLOG_PORT);
        } else if (parts.length == 2) {
            host.set(parts[0]);
            port.set(Integer.parseInt(parts[1]));
        } else {
            LOGGER.warn("Invalid syslogHost setting: {}. Using default", syslogHost);
            host.set("localhost");
            port.set(SYSLOG_PORT);
        }
    }
}
