/*
 * Copyright 2002-2013 SCOOP Software GmbH
 *
 * Licensed 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 de.scoopgmbh.copper.monitoring.server.logging;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.joran.JoranConfigurator;
import ch.qos.logback.classic.util.ContextInitializer;
import ch.qos.logback.core.joran.spi.JoranException;
import de.scoopgmbh.copper.monitoring.server.provider.MonitoringLogbackDataProvider;

public class LogbackConfigManager implements LogConfigManager {
	
	private final MonitoringLogbackDataProvider dataProvider;
	private final LogbackConfigLocationLocator logbackConfigLocationLocator;

	private LoggerContext loggerContext;
	public LogbackConfigManager(MonitoringLogbackDataProvider dataProvider,LogbackConfigLocationLocator logbackConfigLocationLocator){
		loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
		this.dataProvider = dataProvider;
		this.logbackConfigLocationLocator = logbackConfigLocationLocator;
	}
	
	public LogbackConfigManager(MonitoringLogbackDataProvider dataProvider){
		this(dataProvider, new DefaultLogbackConfigLocationLocator());
	}
	
	private String config;
	@Override
	public void updateLogConfig(String config) {
		this.config=config;
		InputStream is = null;	
		try {
			is	= new ByteArrayInputStream(config.getBytes());
			dataProvider.removeFromRootLogger();
			reload(is);
			dataProvider.addToRootLogger();
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			try {
				is.close();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}

	@Override
	public String getLogConfig() {
		if (config!=null){
			return config;
		}

		URL url = logbackConfigLocationLocator.getLogbackConfigLocation();
		
		InputStream inputStream=null;
		try {
			if (url==null){
				return "no logback config found";
			}
			inputStream = url.openStream();
			return de.scoopgmbh.copper.monitoring.server.util.FileUtil.convertStreamToString(inputStream);
		} catch (IOException e) {
			throw new RuntimeException(e);
		} finally {
			try {
				if (inputStream!=null){
					inputStream.close();
				}
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}
	}


	
	//copy from JMXConfigurator to fix api
	private void reload(InputStream in) throws JoranException {
		
//		StatusListenerAsList statusListenerAsList = new StatusListenerAsList();
//
//		addStatusListener(statusListenerAsList);
//		addInfo("Resetting context: " + loggerContext.getName());
		loggerContext.reset();
		// after a reset the statusListenerAsList gets removed as a listener
//		addStatusListener(statusListenerAsList);

		try {
			JoranConfigurator configurator = new JoranConfigurator();
			configurator.setContext(loggerContext);
			configurator.doConfigure(in);
//			addInfo("Context: " + loggerContext.getName() + " reloaded.");
		} finally {
//			removeStatusListener(statusListenerAsList);
//			if (debug) {
//				StatusPrinter.print(statusListenerAsList.getStatusList());
//			}
		}
		
	}
	
	public static interface LogbackConfigLocationLocator{
		public URL getLogbackConfigLocation();
	}
	
	public static class DefaultLogbackConfigLocationLocator implements LogbackConfigLocationLocator{
		@Override
		public URL getLogbackConfigLocation() {
			LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
			ContextInitializer ci = new ContextInitializer(loggerContext);
			return ci.findURLOfDefaultConfigurationFile(true);
		}
	}

}

@@ -774,30 +774,8 @@
 am;%0D
-%0Aimport java.net.URL;%0D
 %0A%0D%0Ai
@@ -2392,18 +2392,36 @@
 %0D%0A%09%09
-URL url = 
+%0D%0A%09%09InputStream inputStream=
 logb
@@ -2476,44 +2476,8 @@
 n();
-%0D%0A%09%09%0D%0A%09%09InputStream inputStream=null
 ;%0D%0A%09
@@ -2491,19 +2491,27 @@
 %0A%09%09%09if (
-url
+inputStream
 ==null)%7B
@@ -2561,44 +2561,8 @@
 %09%7D%0D%0A
-%09%09%09inputStream = url.openStream();%0D%0A
 %09%09%09r
@@ -2660,72 +2660,8 @@
 );%0D%0A
-%09%09%7D catch (IOException e) %7B%0D%0A%09%09%09throw new RuntimeException(e);%0D%0A
 %09%09%7D 
@@ -3724,35 +3724,43 @@
 ator%7B%0D%0A%09%09public 
-URL
+InputStream
  getLogbackConfi
@@ -3901,19 +3901,27 @@
 %09public 
-URL
+InputStream
  getLogb
@@ -4091,24 +4091,35 @@
 rContext);%0D%0A
+%09%09%09try %7B%0D%0A%09
 %09%09%09return ci
@@ -4158,17 +4158,82 @@
 le(true)
-;
+.openStream();%0D%0A%09%09%09%7D catch (Exception e) %7B%0D%0A%09%09%09%09return null;%0D%0A%09%09%09%7D
 %0D%0A%09%09%7D%0D%0A%09

support custom audittrail table, worklfow without versioninfo, pool filter default is now null, configurable logback config location