/*
 * Copyright 2014 gitblit.com.
 *
 * 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 com.gitblit.manager;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileFilter;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.net.URL;
import java.net.URLConnection;
import java.security.DigestInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import ro.fortsoft.pf4j.DefaultExtensionFinder;
import ro.fortsoft.pf4j.DefaultPluginManager;
import ro.fortsoft.pf4j.ExtensionFinder;
import ro.fortsoft.pf4j.PluginClassLoader;
import ro.fortsoft.pf4j.PluginState;
import ro.fortsoft.pf4j.PluginStateEvent;
import ro.fortsoft.pf4j.PluginStateListener;
import ro.fortsoft.pf4j.PluginWrapper;
import ro.fortsoft.pf4j.Version;

import com.gitblit.Constants;
import com.gitblit.Keys;
import com.gitblit.extensions.GitblitPlugin;
import com.gitblit.models.PluginRegistry;
import com.gitblit.models.PluginRegistry.InstallState;
import com.gitblit.models.PluginRegistry.PluginRegistration;
import com.gitblit.models.PluginRegistry.PluginRelease;
import com.gitblit.utils.Base64;
import com.gitblit.utils.FileUtils;
import com.gitblit.utils.JsonUtils;
import com.gitblit.utils.StringUtils;
import com.google.common.io.Files;
import com.google.common.io.InputSupplier;
import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
 * The plugin manager maintains the lifecycle of plugins. It is exposed as
 * Dagger bean. The extension consumers supposed to retrieve plugin manager from
 * the Dagger DI and retrieve extensions provided by active plugins.
 *
 * @author David Ostrovsky
 * @author James Moger
 *
 */
@Singleton
public class PluginManager implements IPluginManager, PluginStateListener {

	private final Logger logger = LoggerFactory.getLogger(getClass());

	private final IRuntimeManager runtimeManager;

	private DefaultPluginManager pf4j;

	// timeout defaults of Maven 3.0.4 in seconds
	private int connectTimeout = 20;

	private int readTimeout = 12800;

	@Inject
	public PluginManager(IRuntimeManager runtimeManager) {
		this.runtimeManager = runtimeManager;
	}

	@Override
	public Version getSystemVersion() {
		return pf4j.getSystemVersion();
	}

	@Override
	public void pluginStateChanged(PluginStateEvent event) {
		logger.debug(event.toString());
	}

	@Override
	public PluginManager start() {
		File dir = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins");
		dir.mkdirs();
		pf4j = new DefaultPluginManager(dir) {
			@Override
		    protected ExtensionFinder createExtensionFinder() {
		    	DefaultExtensionFinder extensionFinder = new DefaultExtensionFinder(this) {
		    		@Override
					protected ExtensionFactory createExtensionFactory() {
		    			return new ExtensionFactory() {
		    				@Override
		    				public Object create(Class<?> extensionType) {
		    					// instantiate && inject the extension
		    					logger.debug("Create instance for extension '{}'", extensionType.getName());
		    					try {
		    						return runtimeManager.getInjector().getInstance(extensionType);
		    					} catch (Exception e) {
		    						logger.error(e.getMessage(), e);
		    					}
		    					return null;
		    				}

		    			};
		    		}
		    	};
		        addPluginStateListener(extensionFinder);

		        return extensionFinder;
		    }
		};

		try {
			Version systemVersion = Version.createVersion(Constants.getVersion());
			pf4j.setSystemVersion(systemVersion);
		} catch (Exception e) {
			logger.error(null, e);
		}
		pf4j.loadPlugins();
		logger.debug("Starting plugins");
		pf4j.startPlugins();
		return this;
	}

	@Override
	public PluginManager stop() {
		logger.debug("Stopping plugins");
		pf4j.stopPlugins();
		return null;
	}

	/**
	 * Installs the plugin from the url.
	 *
	 * @param url
	 * @param verifyChecksum
	 * @return true if successful
	 */
	@Override
	public synchronized boolean installPlugin(String url, boolean verifyChecksum) throws IOException {
		File file = download(url, verifyChecksum);
		if (file == null || !file.exists()) {
			logger.error("Failed to download plugin {}", url);
			return false;
		}

		String pluginId = pf4j.loadPlugin(file);
		if (StringUtils.isEmpty(pluginId)) {
			logger.error("Failed to load plugin {}", file);
			return false;
		}

		// allow the plugin to prepare for operation after installation
		PluginWrapper pluginWrapper = pf4j.getPlugin(pluginId);
		if (pluginWrapper.getPlugin() instanceof GitblitPlugin) {
			((GitblitPlugin) pluginWrapper.getPlugin()).onInstall();
		}

		PluginState state = pf4j.startPlugin(pluginId);
		return PluginState.STARTED.equals(state);
	}

	@Override
	public synchronized boolean upgradePlugin(String pluginId, String url, boolean verifyChecksum) throws IOException {
		// ensure we can download the update BEFORE we remove the existing one
		File file = download(url, verifyChecksum);
		if (file == null || !file.exists()) {
			logger.error("Failed to download plugin {}", url);
			return false;
		}

		Version oldVersion = pf4j.getPlugin(pluginId).getDescriptor().getVersion();
		if (removePlugin(pluginId, false)) {
			String newPluginId = pf4j.loadPlugin(file);
			if (StringUtils.isEmpty(newPluginId)) {
				logger.error("Failed to load plugin {}", file);
				return false;
			}

			// the plugin to handle an upgrade
			PluginWrapper pluginWrapper = pf4j.getPlugin(newPluginId);
			if (pluginWrapper.getPlugin() instanceof GitblitPlugin) {
				((GitblitPlugin) pluginWrapper.getPlugin()).onUpgrade(oldVersion);
			}

			PluginState state = pf4j.startPlugin(newPluginId);
			return PluginState.STARTED.equals(state);
		} else {
			logger.error("Failed to delete plugin {}", pluginId);
		}
		return false;
	}

	@Override
	public synchronized boolean disablePlugin(String pluginId) {
		return pf4j.disablePlugin(pluginId);
	}

	@Override
	public synchronized boolean enablePlugin(String pluginId) {
		if (pf4j.enablePlugin(pluginId)) {
			return PluginState.STARTED == pf4j.startPlugin(pluginId);
		}
		return false;
	}

	@Override
	public synchronized boolean uninstallPlugin(String pluginId) {
		return removePlugin(pluginId, true);
	}

	protected boolean removePlugin(String pluginId, boolean isUninstall) {
		PluginWrapper pluginWrapper = getPlugin(pluginId);
		final String name = pluginWrapper.getPluginPath().substring(1);

		if (isUninstall) {
			// allow the plugin to prepare for uninstallation
			if (pluginWrapper.getPlugin() instanceof GitblitPlugin) {
				((GitblitPlugin) pluginWrapper.getPlugin()).onUninstall();
			}
		}

		if (pf4j.deletePlugin(pluginId)) {

			// delete the checksums
			File pFolder = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins");
			File [] checksums = pFolder.listFiles(new FileFilter() {
				@Override
				public boolean accept(File file) {
					if (!file.isFile()) {
						return false;
					}

					return file.getName().startsWith(name) &&
							(file.getName().toLowerCase().endsWith(".sha1")
									|| file.getName().toLowerCase().endsWith(".md5"));
				}
			});

			if (checksums != null) {
				for (File checksum : checksums) {
					checksum.delete();
				}
			}
			return true;
		}
		return false;
	}

	@Override
	public synchronized PluginState startPlugin(String pluginId) {
		return pf4j.startPlugin(pluginId);
	}

	@Override
	public synchronized PluginState stopPlugin(String pluginId) {
		return pf4j.stopPlugin(pluginId);
	}

	@Override
	public synchronized void startPlugins() {
		pf4j.startPlugins();
	}

	@Override
	public synchronized void stopPlugins() {
		pf4j.stopPlugins();
	}

	@Override
	public synchronized List<PluginWrapper> getPlugins() {
		return pf4j.getPlugins();
	}

	@Override
	public synchronized PluginWrapper getPlugin(String pluginId) {
		return pf4j.getPlugin(pluginId);
	}

	@Override
	public synchronized List<Class<?>> getExtensionClasses(String pluginId) {
		List<Class<?>> list = new ArrayList<Class<?>>();
		PluginClassLoader loader = pf4j.getPluginClassLoader(pluginId);
		for (String className : pf4j.getExtensionClassNames(pluginId)) {
			try {
				list.add(loader.loadClass(className));
			} catch (ClassNotFoundException e) {
				logger.error(String.format("Failed to find %s in %s", className, pluginId), e);
			}
		}
		return list;
	}

	@Override
	public synchronized <T> List<T> getExtensions(Class<T> type) {
		return pf4j.getExtensions(type);
	}

	@Override
	public synchronized PluginWrapper whichPlugin(Class<?> clazz) {
		return pf4j.whichPlugin(clazz);
	}

	@Override
	public synchronized boolean refreshRegistry(boolean verifyChecksum) {
		String dr = "http://gitblit.github.io/gitblit-registry/plugins.json";
		String url = runtimeManager.getSettings().getString(Keys.plugins.registry, dr);
		try {
			File file = download(url, verifyChecksum);
			if (file != null && file.exists()) {
				URL selfUrl = new URL(url.substring(0, url.lastIndexOf('/')));
				// replace ${self} with the registry url
				String content = FileUtils.readContent(file, "\n");
				content = content.replace("${self}", selfUrl.toString());
				FileUtils.writeContent(file, content);
			}
		} catch (Exception e) {
			logger.error(String.format("Failed to retrieve plugins.json from %s", url), e);
		}
		return false;
	}

	protected List<PluginRegistry> getRegistries() {
		List<PluginRegistry> list = new ArrayList<PluginRegistry>();
		File folder = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins");
		FileFilter jsonFilter = new FileFilter() {
			@Override
			public boolean accept(File file) {
				return !file.isDirectory() && file.getName().toLowerCase().endsWith(".json");
			}
		};

		File[] files = folder.listFiles(jsonFilter);
		if (files == null || files.length == 0) {
			// automatically retrieve the registry if we don't have a local copy
			refreshRegistry(true);
			files = folder.listFiles(jsonFilter);
		}

		if (files == null || files.length == 0) {
			return list;
		}

		for (File file : files) {
			PluginRegistry registry = null;
			try {
				String json = FileUtils.readContent(file, "\n");
				registry = JsonUtils.fromJsonString(json, PluginRegistry.class);
				registry.setup();
			} catch (Exception e) {
				logger.error("Failed to deserialize " + file, e);
			}
			if (registry != null) {
				list.add(registry);
			}
		}
		return list;
	}

	@Override
	public synchronized List<PluginRegistration> getRegisteredPlugins() {
		List<PluginRegistration> list = new ArrayList<PluginRegistration>();
		Map<String, PluginRegistration> map = new TreeMap<String, PluginRegistration>();
		for (PluginRegistry registry : getRegistries()) {
			list.addAll(registry.registrations);
			for (PluginRegistration reg : list) {
				reg.installedRelease = null;
				map.put(reg.id, reg);
			}
		}

		for (PluginWrapper pw : pf4j.getPlugins()) {
			String id = pw.getDescriptor().getPluginId();
			Version pv = pw.getDescriptor().getVersion();
			PluginRegistration reg = map.get(id);
			if (reg != null) {
				reg.installedRelease = pv.toString();
			}
		}
		return list;
	}

	@Override
	public synchronized List<PluginRegistration> getRegisteredPlugins(InstallState state) {
		List<PluginRegistration> list = getRegisteredPlugins();
		Iterator<PluginRegistration> itr = list.iterator();
		while (itr.hasNext()) {
			if (state != itr.next().getInstallState(getSystemVersion())) {
				itr.remove();
			}
		}
		return list;
	}

	@Override
	public synchronized PluginRegistration lookupPlugin(String pluginId) {
		for (PluginRegistration reg : getRegisteredPlugins()) {
			if (reg.id.equalsIgnoreCase(pluginId)) {
				return reg;
			}
		}
		return null;
	}

	@Override
	public synchronized PluginRelease lookupRelease(String pluginId, String version) {
		PluginRegistration reg = lookupPlugin(pluginId);
		if (reg == null) {
			return null;
		}

		PluginRelease pv;
		if (StringUtils.isEmpty(version)) {
			pv = reg.getCurrentRelease(getSystemVersion());
		} else {
			pv = reg.getRelease(version);
		}
		return pv;
	}

	/**
	 * Downloads a file with optional checksum verification.
	 *
	 * @param url
	 * @param verifyChecksum
	 * @return
	 * @throws IOException
	 */
	protected File download(String url, boolean verifyChecksum) throws IOException {
		File file = downloadFile(url);

		File sha1File = null;
		try {
			sha1File = downloadFile(url + ".sha1");
		} catch (IOException e) {
		}

		File md5File = null;
		try {
			md5File = downloadFile(url + ".md5");
		} catch (IOException e) {

		}

		if (sha1File == null && md5File == null && verifyChecksum) {
			throw new IOException("Missing SHA1 and MD5 checksums for " + url);
		}

		String expected;
		MessageDigest md = null;
		if (sha1File != null && sha1File.exists()) {
			// prefer SHA1 to MD5
			expected = FileUtils.readContent(sha1File, "\n").split(" ")[0].trim();
			try {
				md = MessageDigest.getInstance("SHA-1");
			} catch (NoSuchAlgorithmException e) {
				logger.error(null, e);
			}
		} else {
			expected = FileUtils.readContent(md5File, "\n").split(" ")[0].trim();
			try {
				md = MessageDigest.getInstance("MD5");
			} catch (Exception e) {
				logger.error(null, e);
			}
		}

		// calculate the checksum
		FileInputStream is = null;
		try {
			is = new FileInputStream(file);
			DigestInputStream dis = new DigestInputStream(is, md);
			byte [] buffer = new byte[1024];
			while ((dis.read(buffer)) > -1) {
				// read
			}
			dis.close();

			byte [] digest = md.digest();
			String calculated = StringUtils.toHex(digest).trim();

			if (!expected.equals(calculated)) {
				String msg = String.format("Invalid checksum for %s\nAlgorithm:  %s\nExpected:   %s\nCalculated: %s",
						file.getAbsolutePath(),
						md.getAlgorithm(),
						expected,
						calculated);
				file.delete();
				throw new IOException(msg);
			}
		} finally {
			if (is != null) {
				is.close();
			}
		}
		return file;
	}

	/**
	 * Download a file to the plugins folder.
	 *
	 * @param url
	 * @return the downloaded file
	 * @throws IOException
	 */
	protected File downloadFile(String url) throws IOException {
		File pFolder = runtimeManager.getFileOrFolder(Keys.plugins.folder, "${baseFolder}/plugins");
		pFolder.mkdirs();
		File tmpFile = new File(pFolder, StringUtils.getSHA1(url) + ".tmp");
		if (tmpFile.exists()) {
			tmpFile.delete();
		}

		URL u = new URL(url);
		final URLConnection conn = getConnection(u);

		// try to get the server-specified last-modified date of this artifact
		long lastModified = conn.getHeaderFieldDate("Last-Modified", System.currentTimeMillis());

		Files.copy(new InputSupplier<InputStream>() {
			@Override
			public InputStream getInput() throws IOException {
				return new BufferedInputStream(conn.getInputStream());
			}
		}, tmpFile);

		File destFile = new File(pFolder, StringUtils.getLastPathElement(u.getPath()));
		if (destFile.exists()) {
			destFile.delete();
		}
		tmpFile.renameTo(destFile);
		destFile.setLastModified(lastModified);

		return destFile;
	}

	protected URLConnection getConnection(URL url) throws IOException {
		java.net.Proxy proxy = getProxy(url);
		HttpURLConnection conn = (HttpURLConnection) url.openConnection(proxy);
		if (java.net.Proxy.Type.DIRECT != proxy.type()) {
			String auth = getProxyAuthorization(url);
			conn.setRequestProperty("Proxy-Authorization", auth);
		}

		String username = null;
		String password = null;
		if (!StringUtils.isEmpty(username) && !StringUtils.isEmpty(password)) {
			// set basic authentication header
			String auth = Base64.encodeBytes((username + ":" + password).getBytes());
			conn.setRequestProperty("Authorization", "Basic " + auth);
		}

		// configure timeouts
		conn.setConnectTimeout(connectTimeout * 1000);
		conn.setReadTimeout(readTimeout * 1000);

		switch (conn.getResponseCode()) {
		case HttpURLConnection.HTTP_MOVED_TEMP:
		case HttpURLConnection.HTTP_MOVED_PERM:
			// handle redirects by closing this connection and opening a new
			// one to the new location of the requested resource
			String newLocation = conn.getHeaderField("Location");
			if (!StringUtils.isEmpty(newLocation)) {
				logger.info("following redirect to {0}", newLocation);
				conn.disconnect();
				return getConnection(new URL(newLocation));
			}
		}

		return conn;
	}

	protected Proxy getProxy(URL url) {
		return java.net.Proxy.NO_PROXY;
	}

	protected String getProxyAuthorization(URL url) {
		return "";
	}
}
