/*******************************************************************************
 * Copyright (c) 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.osgi.internal.log;

import java.lang.reflect.*;
import java.util.*;
import org.osgi.framework.*;
import org.osgi.service.log.LogLevel;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;

class ConfigAdminListener implements ServiceTrackerCustomizer<Object, ServiceRegistration<?>> {

	private static final String CLASS_CONFIG_ADMIN = "org.osgi.service.cm.ConfigurationAdmin"; //$NON-NLS-1$
	private static final String METHOD_CONFIG_ADMIN_GET_CONFIGURATION = "getConfiguration"; //$NON-NLS-1$
	private static final String METHOD_CONFIG_ADMIN_LIST_CONFIGURATIONS = "listConfigurations"; //$NON-NLS-1$

	private static final String CLASS_SYNC_CONFIG_LISTENER = "org.osgi.service.cm.SynchronousConfigurationListener"; //$NON-NLS-1$
	private static final String CLASS_CONFIG_EVENT = "org.osgi.service.cm.ConfigurationEvent"; //$NON-NLS-1$
	private static final String METHOD_CONFIG_EVENT_GET_PID = "getPid"; //$NON-NLS-1$
	private static final String METHOD_CONFIG_EVENT_GET_FACTORY_PID = "getFactoryPid"; //$NON-NLS-1$
	private static final String METHOD_CONFIG_EVENT_GET_REFERENCE = "getReference"; //$NON-NLS-1$
	private static final String METHOD_CONFIG_EVENT_GET_TYPE = "getType"; //$NON-NLS-1$
	private static final int CM_UPDATED = 1;
	private static final int CM_DELETED = 2;
	private static final int CM_LOCATION_CHANGED = 3;

	private static final String CLASS_CONFIG = "org.osgi.service.cm.Configuration"; //$NON-NLS-1$
	private static final String METHOD_CONFIG_GET_PROPERTIES = "getProperties"; //$NON-NLS-1$
	private static final String METHOD_CONFIG_GET_PID = "getPid"; //$NON-NLS-1$
	private static final String METHOD_CONFIG_GET_FACTORY_PID = "getFactoryPid"; //$NON-NLS-1$

	private static final String PID_PREFIX_LOG_ADMIN = "org.osgi.service.log.admin"; //$NON-NLS-1$
	// using String constructor here to avoid interning
	private static final String PID_FILTER = '(' + Constants.SERVICE_PID + '=' + PID_PREFIX_LOG_ADMIN + '*' + ')';

	private final ServiceTracker<Object, ServiceRegistration<?>> configTracker;
	final ExtendedLogServiceFactory factory;
	final BundleContext context;

	ConfigAdminListener(BundleContext context, ExtendedLogServiceFactory factory) {
		this.context = context;
		this.configTracker = new ServiceTracker<>(context, CLASS_CONFIG_ADMIN, this);
		this.factory = factory;
	}

	void start() {
		configTracker.open();
	}

	void stop() {
		configTracker.close();
	}

	private ServiceRegistration<?> registerConfigurationListener(ServiceReference<?> configRef) {
		try {
			Class<?> listenerClass = configRef.getBundle().loadClass(CLASS_SYNC_CONFIG_LISTENER);
			return registerProxyConfigListener(configRef, listenerClass);
		} catch (ClassNotFoundException | NoSuchMethodException e) {
			throw new RuntimeException(CLASS_SYNC_CONFIG_LISTENER, e);
		}
	}

	private ServiceRegistration<?> registerProxyConfigListener(ServiceReference<?> configRef, Class<?> listenerClass) throws ClassNotFoundException, NoSuchMethodException {
		LoggerContextConfiguration loggerConfiguration = new LoggerContextConfiguration(listenerClass, configRef);
		return loggerConfiguration.register();
	}

	@Override
	public ServiceRegistration<?> addingService(ServiceReference<Object> configRef) {
		return registerConfigurationListener(configRef);
	}

	@Override
	public void modifiedService(ServiceReference<Object> configRef, ServiceRegistration<?> configReg) {
		// Nothing to do
	}

	@Override
	public void removedService(ServiceReference<Object> configRef, ServiceRegistration<?> loggerConfiguration) {
		loggerConfiguration.unregister();
	}

	class LoggerContextConfiguration implements InvocationHandler {
		private final Object listenerProxy;
		private final Object configAdmin;
		private final ServiceReference<?> configAdminRef;

		private final Class<?> configClass;
		private final Method getConfigProperties;
		private final Method getConfigPid;
		private final Method getConfigFactoryPid;

		private final Class<?> configAdminClass;
		private final Method getConfiguration;
		private final Method listConfigurations;

		private final Class<?> configEventClass;
		private final Method getEventPid;
		private final Method getEventFactoryPid;
		private final Method getEventReference;
		private final Method getEventType;

		public LoggerContextConfiguration(Class<?> listenerClass, ServiceReference<?> ref) throws ClassNotFoundException, NoSuchMethodException {
			listenerProxy = Proxy.newProxyInstance(listenerClass.getClassLoader(), new Class[] {listenerClass}, this);
			configAdminRef = ref;
			ClassLoader cl = listenerClass.getClassLoader();

			configClass = cl.loadClass(CLASS_CONFIG);
			getConfigProperties = configClass.getMethod(METHOD_CONFIG_GET_PROPERTIES);
			getConfigFactoryPid = configClass.getMethod(METHOD_CONFIG_GET_FACTORY_PID);
			getConfigPid = configClass.getMethod(METHOD_CONFIG_GET_PID);

			configAdminClass = cl.loadClass(CLASS_CONFIG_ADMIN);
			getConfiguration = configAdminClass.getMethod(METHOD_CONFIG_ADMIN_GET_CONFIGURATION, String.class, String.class);
			listConfigurations = configAdminClass.getMethod(METHOD_CONFIG_ADMIN_LIST_CONFIGURATIONS, String.class);

			configEventClass = cl.loadClass(CLASS_CONFIG_EVENT);
			getEventPid = configEventClass.getMethod(METHOD_CONFIG_EVENT_GET_PID);
			getEventFactoryPid = configEventClass.getMethod(METHOD_CONFIG_EVENT_GET_FACTORY_PID);
			getEventReference = configEventClass.getMethod(METHOD_CONFIG_EVENT_GET_REFERENCE);
			getEventType = configEventClass.getMethod(METHOD_CONFIG_EVENT_GET_TYPE);

			configAdmin = context.getService(ref);
		}

		public ServiceRegistration<?> register() {
			// register it with the config admin context to ensure consistent class space
			Bundle configBundle = configAdminRef.getBundle();
			BundleContext configContext = configBundle != null ? configAdminRef.getBundle().getBundleContext() : null;
			if (configContext == null) {
				// seems the bundle has stopped!
				return null;
			}
			ServiceRegistration<?> registration = configContext.registerService(CLASS_SYNC_CONFIG_LISTENER, listenerProxy, null);

			try {
				Object[] configs = (Object[]) listConfigurations.invoke(configAdmin, PID_FILTER);
				if (configs != null) {
					for (Object config : configs) {
						String factoryPid = (String) getConfigFactoryPid.invoke(config);
						if (factoryPid != null) {
							continue;
						}
						String pid = (String) getConfigPid.invoke(config);
						String contextName = getContextName(pid);
						@SuppressWarnings("unchecked")
						Dictionary<String, Object> configDictionary = (Dictionary<String, Object>) getConfigProperties.invoke(config);
						if (configDictionary != null) {
							setLogLevels(contextName, getLogLevels(configDictionary));
						}
					}
				}
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				throw new RuntimeException(e);
			}
			return registration;
		}

		@Override
		public Object invoke(Object proxy, Method method, Object[] event) throws Throwable {
			// There is only one method on ConfigurationListener, no need to check the method type
			// ConfigurationListener::configurationEvent(ConfigurationEvent)
			if (!configAdminRef.equals(getReference(event))) {
				// ignore other config admin events
				return null;
			}

			String pid = getEventPid(event);
			if (pid == null) {
				// a factory pid or more likely doesn't have the correct prefix; ignore
				return null;
			}

			int type = getType(event);
			if (type == CM_LOCATION_CHANGED) {
				// TODO not sure if we should check location or not
				return null;
			}

			String contextName = getContextName(pid);
			if (type == CM_DELETED) {
				setLogLevels(contextName, Collections.<String, LogLevel> emptyMap());
				return null;
			}

			if (type == CM_UPDATED) {
				Dictionary<String, Object> configDictionary = findConfiguration(pid);
				if (configDictionary == null) {
					// Configuration got deleted before we could get it so treat as deleted
					setLogLevels(contextName, Collections.<String, LogLevel> emptyMap());
					return null;
				}

				Map<String, LogLevel> levelConfig = getLogLevels(configDictionary);
				setLogLevels(contextName, levelConfig);
			}
			return null;
		}

		private String getContextName(String pid) {
			if (PID_PREFIX_LOG_ADMIN.equals(pid)) {
				return null;
			}
			char separator = pid.charAt(PID_PREFIX_LOG_ADMIN.length());
			if (separator != '|') {
				return null;
			}
			int startName = PID_PREFIX_LOG_ADMIN.length() + 1;
			return pid.substring(startName);
		}

		private Map<String, LogLevel> getLogLevels(Dictionary<String, Object> configDictionary) {
			Map<String, LogLevel> result = new HashMap<>(configDictionary.size());
			for (Enumeration<String> keys = configDictionary.keys(); keys.hasMoreElements();) {
				String key = keys.nextElement();
				Object v = configDictionary.get(key);
				if (v instanceof String) {
					try {
						result.put(key, LogLevel.valueOf((String) v));
					} catch (IllegalArgumentException e) {
						// ignore invalid values
					}
				}
			}
			return result;
		}

		private Object getReference(Object[] event) {
			try {
				return getEventReference.invoke(event[0]);
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				throw new RuntimeException(e);
			}
		}

		private String getEventPid(Object[] event) {
			try {
				String factoryPid = (String) getEventFactoryPid.invoke(event[0]);
				if (factoryPid != null) {
					// ignore factory pids
					return null;
				}
				String pid = (String) getEventPid.invoke(event[0]);
				if (pid.startsWith(PID_PREFIX_LOG_ADMIN)) {
					return pid;
				}
				return null;
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				throw new RuntimeException(e);
			}
		}

		private int getType(Object[] event) {
			try {
				Integer type = (Integer) getEventType.invoke(event[0]);
				return type == null ? 0 : type.intValue();
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				throw new RuntimeException(e);
			}
		}

		@SuppressWarnings("unchecked")
		private Dictionary<String, Object> findConfiguration(String pid) {
			try {
				Object config = getConfiguration.invoke(configAdmin, pid, null);
				return (Dictionary<String, Object>) getConfigProperties.invoke(config);
			} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
				throw new RuntimeException(e);
			}
		}

		private void setLogLevels(String contextName, Map<String, LogLevel> logLevels) {
			factory.getLoggerAdmin().getLoggerContext(contextName).setLogLevels(logLevels);
		}
	}
}
