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


import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.chainsaw.plugins.PluginClassLoaderFactory;
import org.apache.log4j.plugins.Plugin;
import org.apache.log4j.plugins.PluginRegistry;
import org.apache.log4j.plugins.Receiver;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggerRepositoryEx;
import org.w3c.dom.Document;
import org.w3c.dom.Element;


/**
 * Helper class to assisit with all the known Receivers.
 * 
 * A local resource 'known.receivers' is read in on initialization
 * with each line representing the FQN of the Class that is a recognised Receiver.
 * 
 * @author Paul Smith &lt;psmith@apache.org&gt;
 *
 */
public class ReceiversHelper {

    private static final ReceiversHelper instance = new ReceiversHelper();

    private final Logger logger = LogManager.getLogger(ReceiversHelper.class);
    private List<Class> receiverClassList = new ArrayList<>();
    /**
     *
     */
    private ReceiversHelper() {

        URL url = this.getClass().getClassLoader().getResource(
            this.getClass().getPackage().getName().replace('.','/') + "/known.receivers");
        if (url == null) {
            logger.warn("Failed to locate known.receivers file");
            return;
        }
        LineNumberReader stream = null;
        try {

            stream = new LineNumberReader(new InputStreamReader(url.openStream()));
            String line;
            // we need the special Classloader, because under Web start, optional jars might be local
            // to this workstation
            ClassLoader classLoader = PluginClassLoaderFactory.getInstance().getClassLoader();

            while ((line = stream.readLine()) != null) {
            	
            	try {
            		if (line.startsWith("#") || (line.length() == 0)) {
            			continue;
            		}
            		Class receiverClass = classLoader.loadClass(line);
            		receiverClassList.add(receiverClass);
            		logger.debug("Located known Receiver class " + receiverClass.getName());
            	} catch (ClassNotFoundException e) {
            		logger.warn("Failed to locate Receiver class:" + line);
            	}
            	catch (NoClassDefFoundError e) {
            		logger.error("Failed to locate Receiver class:" + line + ", looks like a dependent class is missing from the classpath", e);
            	}
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (stream != null) {
                try {
                    stream.close();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
    }


    public static ReceiversHelper getInstance() {
        return instance;
    }


    /**
     * Returns an unmodifiable list of Class objects which represent all the 'known'
     * Receiver classes.
     * @return known receiver classes
     */
    public List getKnownReceiverClasses() {
      return Collections.unmodifiableList(receiverClassList);
    }


  public void saveReceiverConfiguration(File file) {
    LoggerRepository repo = LogManager.getLoggerRepository();
    PluginRegistry pluginRegistry = ((LoggerRepositoryEx) repo).getPluginRegistry();
    List<Plugin> fullPluginList = pluginRegistry.getPlugins();
    List<Plugin> pluginList = new ArrayList<>();
      for (Object aFullPluginList : fullPluginList) {
          Plugin thisPlugin = (Plugin) aFullPluginList;
          if (thisPlugin instanceof Receiver) {
              pluginList.add(thisPlugin);
          }
      }
    //remove everything that isn't a receiver..otherwise, we'd create an empty config file
    try {
        if (pluginList.size() > 0) {
            //we programmatically register the ZeroConf plugin in the plugin registry
            DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
            factory.setNamespaceAware(true);
            DocumentBuilder builder = factory.newDocumentBuilder();
            Document document = builder.newDocument();
            Element rootElement = document.createElementNS("http://jakarta.apache.org/log4j/", "configuration");
            rootElement.setPrefix("log4j");
            rootElement.setAttribute("xmlns:log4j", "http://jakarta.apache.org/log4j/");
            rootElement.setAttribute("debug", "true");

            for (Object aPluginList : pluginList) {
                Receiver receiver;

                if (aPluginList instanceof Receiver) {
                    receiver = (Receiver) aPluginList;
                } else {
                    continue;
                }

                Element pluginElement = document.createElement("plugin");
                pluginElement.setAttribute("name", receiver.getName());
                pluginElement.setAttribute("class", receiver.getClass().getName());

                BeanInfo beanInfo = Introspector.getBeanInfo(receiver.getClass());
                List<PropertyDescriptor> list = new ArrayList<>(Arrays.asList(beanInfo.getPropertyDescriptors()));

                for (Object aList : list) {
                    PropertyDescriptor d = (PropertyDescriptor) aList;
                    //don't serialize the loggerRepository property for subclasses of componentbase..
                    //easier to change this than tweak componentbase right now..
                    if (d.getReadMethod().getName().equals("getLoggerRepository")) {
                        continue;
                    }
                    Object o = d.getReadMethod().invoke(receiver);
                    if (o != null) {
                        Element paramElement = document.createElement("param");
                        paramElement.setAttribute("name", d.getName());
                        paramElement.setAttribute("value", o.toString());
                        pluginElement.appendChild(paramElement);
                    }
                }

                rootElement.appendChild(pluginElement);

            }

            TransformerFactory transformerFactory = TransformerFactory.newInstance();
            Transformer transformer = transformerFactory.newTransformer();
            transformer.setOutputProperty(OutputKeys.INDENT, "yes");
            transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "4");
            DOMSource source = new DOMSource(rootElement);
            FileOutputStream stream = new FileOutputStream(file);
            StreamResult result = new StreamResult(stream);
            transformer.transform(source, result);
            stream.close();
        }

    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}
