/*******************************************************************************
 * Copyright (c) 2000, 2006 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.update.internal.core;

import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.osgi.util.NLS;
import org.eclipse.update.configuration.ILocalSite;
import org.eclipse.update.core.ISite;
import org.eclipse.update.core.ISiteFactory;
import org.eclipse.update.core.ISiteFactoryExtension;
import org.eclipse.update.core.JarContentReference;
import org.eclipse.update.core.Site;
import org.eclipse.update.core.Utilities;
import org.eclipse.update.core.model.InvalidSiteTypeException;
import org.eclipse.update.internal.core.connection.ConnectionFactory;
import org.eclipse.update.internal.core.connection.IResponse;
import org.eclipse.update.internal.model.ITimestamp;

/**
 * 
 */
public class InternalSiteManager {

	public static ILocalSite localSite;

	public static final String DEFAULT_SITE_TYPE = SiteURLContentProvider.SITE_TYPE;
	private static final String DEFAULT_EXECUTABLE_SITE_TYPE = SiteFileContentProvider.SITE_TYPE;

	private static Map estimates;

	// cache found sites
	private static Map sites = new HashMap();
	// cache http updated url
	private static Map httpSitesUpdatedUrls = new HashMap();
	// cache timestamps
	private static Map siteTimestamps = new HashMap();
	public static boolean globalUseCache = true;

	// true if an exception occured creating localSite
	// so we cache it and don't attempt to create it again
	private static CoreException exceptionOccured = null;

	/*
	 * @see SiteManager#getLocalSite()
	 */
	public static ILocalSite getLocalSite() throws CoreException {
		return internalGetLocalSite();
	}

	/*
	 * Internal call if optimistic reconciliation needed
	 */
	private static ILocalSite internalGetLocalSite() throws CoreException {

		// if an exception occured while retrieving the Site
		// rethrow it
		if (exceptionOccured != null)
			throw exceptionOccured;

		if (localSite == null) {
			try {
				localSite = LocalSite.internalGetLocalSite();
			} catch (CoreException e) {
				exceptionOccured = e;
				throw e;
			}
		}
		return localSite;
	}
	
	private static boolean isValidCachedSite(URL siteURL) {
		if (!sites.containsKey(siteURL.toExternalForm()))
			return false;
			
		Long timestamp = (Long)siteTimestamps.get(siteURL);
		if (timestamp == null)
			return false;
		long localLastModified = timestamp.longValue();
		
		return UpdateManagerUtils.isSameTimestamp(siteURL, localLastModified);
	}

	/*
	 * @see ILocalSite#getSite(URL)
	 */
	public static ISite getSite(URL siteURL, boolean useCache, IProgressMonitor monitor) throws CoreException {
		ISite site = null;
		if (monitor==null) monitor = new NullProgressMonitor();

		if (siteURL == null)
			return null;

		// use cache if set up globally (globalUseCache=true)
		// and passed as parameter (useCache=true)
		if (httpSitesUpdatedUrls.containsKey(siteURL.toExternalForm())) {
			siteURL = (URL)httpSitesUpdatedUrls.get(siteURL.toExternalForm());
		}
		String siteURLString = siteURL.toExternalForm();
		if ((useCache && globalUseCache) && isValidCachedSite(siteURL)) {
			site = (ISite) sites.get(siteURLString);
			UpdateCore.getPlugin().getUpdateSession().markVisited(site.getURL());
			return site;
		}
		
		// try adding "eclipse" to the site url, in case this is an extension site
		if ("file".equals(siteURL.getProtocol()) ) { //$NON-NLS-1$
			File f = new File(siteURL.getFile());
			if (f.isDirectory() && !"eclipse".equals(f.getName())) { //$NON-NLS-1$
				f = new File(f, "eclipse"); //$NON-NLS-1$
				try {
					if ((useCache && globalUseCache) && isValidCachedSite(f.toURL())) {
						site = (ISite) sites.get(f.toURL().toExternalForm());
						return site;
					}
				} catch (MalformedURLException e) {
				}	
			}
		}

		// consider file protocol also if the URL points to a directory
		// and no site.xml exist
		// if the user points to a file, consider DEFAULT_SITE_TYPE
		// site.xml will have to specify the type
		boolean fileProtocol = "file".equalsIgnoreCase(siteURL.getProtocol()); //$NON-NLS-1$
		boolean directoryExists = false;
		if (fileProtocol) {
			File dir;
			dir = new File(siteURL.getFile());
			if (dir != null && dir.isDirectory()) {
				if (!(new File(dir, Site.SITE_XML).exists()))
					directoryExists = true;
			}
		}

		//PERF: if file: <path>/ and directory exists then consider executable
		monitor.beginTask(Messages.InternalSiteManager_ConnectingToSite, 8); 
		if (fileProtocol && directoryExists) {
			site = attemptCreateSite(DEFAULT_EXECUTABLE_SITE_TYPE, siteURL, monitor);
			monitor.worked(4); // only one attempt
		} else {
			try {
				monitor.worked(3);
				site = attemptCreateSite(DEFAULT_SITE_TYPE, siteURL, monitor);
				monitor.worked(1);
			} catch (CoreException preservedException) {
				if (!monitor.isCanceled()) {
					// attempt a retry is the protocol is file, with executbale type
					if (!fileProtocol)
						throw preservedException;

					try {
						site = attemptCreateSite(DEFAULT_EXECUTABLE_SITE_TYPE, siteURL, monitor);
					} catch (CoreException retryException) {
						IStatus firstStatus = preservedException.getStatus();
						MultiStatus multi = new MultiStatus(firstStatus.getPlugin(), IStatus.OK, Messages.InternalSiteManager_FailedRetryAccessingSite, retryException); 
						multi.addAll(firstStatus);
						throw preservedException;
					}
				}
			}
		}

		if (site != null) {
			sites.put(site.getURL().toExternalForm(), site);
			UpdateCore.getPlugin().getUpdateSession().markVisited(site.getURL());
			if (site instanceof ITimestamp) {
				siteTimestamps.put(site.getURL(), new Long(((ITimestamp)site).getTimestamp().getTime()));
			} else {
				try {
					IResponse response = ConnectionFactory.get(URLEncoder.encode(siteURL));
					siteTimestamps.put(siteURL, new Long(response.getLastModified()));
				} catch (MalformedURLException e) {
				} catch (IOException e) {
				}
			}
		}

		//flush the JarFile we may hold on to
		// we keep the temp not to create them again
		JarContentReference.shutdown(); // make sure we are not leaving jars open for this site

		//flush mapping of downloaded JAR files
		// FIXME : provide better cache flushing after 2.1
		// FIXED: everything downloaded is cached and timestamped.
		//        Timestamps are compared to lastModifed on the server
		//        and we download only when there is a differenc
		// Utilities.flushLocalFile();

		return site;
	}

	/*
	 * Attempt to create a site
	 * if the site guessed is not the type found,
	 * attempt to create a type with the type found in the site.xml
	 */
	private static ISite attemptCreateSite(String guessedTypeSite, URL siteURL, IProgressMonitor monitor) throws CoreException {
		if (monitor == null) monitor = new NullProgressMonitor();
		ISite site = null;

		try {
			monitor.worked(1);
			site = createSite(guessedTypeSite, siteURL, monitor);
			monitor.worked(1); // if no error, occurs the retry branch doesn't need to be executed
		} catch (InvalidSiteTypeException e) {
			if (monitor.isCanceled()) return null;

			// the type in the site.xml is not the one expected	
			// attempt to use this type instead	
			//DEBUG:
			if (UpdateCore.DEBUG && UpdateCore.DEBUG_SHOW_TYPE) {
				UpdateCore.debug("The Site :" + siteURL.toExternalForm() + " is a different type than the guessed type based on the protocol. new Type:" + e.getNewType());	//$NON-NLS-1$ //$NON-NLS-2$ 
			}

			try {
				if (e.getNewType() == null)
					throw e;
				site = createSite(e.getNewType(), siteURL, monitor);
			} catch (InvalidSiteTypeException e1) {
				throw Utilities.newCoreException(NLS.bind(Messages.InternalSiteManager_UnableToCreateSiteWithType, (new String[] { e.getNewType(), siteURL.toExternalForm() })), e1); 
			}
		}

		return site;
	}

	/*
	 * create an instance of a class that implements ISite
	 * 
	 * the URL can be of the following form
	 * 1 protocol://...../
	 * 2 protocol://.....
	 * 3 protocol://..../site.xml
	 * 4 protocol://...#...
	 * 
	 * 1 If the file of the file of teh url ends with '/', attempt to open the stream.
	 * if it fails, add site.xml and attempt to open the stream
	 * 
	 * 2 attempt to open the stream
	 * 	fail
	 * 		add '/site.xml' and attempt to open the stream
	 * 	sucess
	 * 		attempt to parse, if it fails, add '/site.xml' and attempt to open the stream
	 * 
	 * 3 open the stream
	 * 
	 * 4 open the stream	
	 */
	private static ISite createSite(String siteType, URL url, IProgressMonitor monitor) throws CoreException, InvalidSiteTypeException {
		
		if (monitor == null) monitor = new NullProgressMonitor();
		//ISite site = null;
		ISiteFactory factory = SiteTypeFactory.getInstance().getFactory(siteType);
		URL fixedUrl;
		
		// see if we need to (and can) fix url by adding site.xml to it
		try {
			if ( (url.getRef() != null) || (url.getFile().endsWith(Site.SITE_XML) || (url.getProtocol().equalsIgnoreCase("file")))) { //$NON-NLS-1$
			 	fixedUrl = url;
			} else if (url.getFile().endsWith("/")) { //$NON-NLS-1$
				fixedUrl = new URL(url, Site.SITE_XML);
			} else {
				fixedUrl = new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile() + "/" + Site.SITE_XML);	//$NON-NLS-1$
			}
		} catch (MalformedURLException mue) {
			fixedUrl = url;
		}
		
		try {
			try { 
				monitor.worked(1);
				return createSite( factory, fixedUrl, url, monitor);
			} catch (CoreException ce) {
				if (monitor.isCanceled()) 
					return null;
			
				if (!fixedUrl.equals(url)) {
					// try with original url
					 return createSite( factory, url, url, monitor);
				} else if (url.getProtocol().equalsIgnoreCase("file") && ! url.getFile().endsWith(Site.SITE_XML)){ //$NON-NLS-1$
					try {
						if (url.getFile().endsWith("/")) { //$NON-NLS-1$
							return createSite(factory, new URL(url,
									Site.SITE_XML), url, monitor);
						} else {
							return createSite(factory, new URL(url
									.getProtocol(), url.getHost(), url
									.getPort(), url.getFile()
									+ "/" + Site.SITE_XML), url, monitor); //$NON-NLS-1$							
						}
					} catch (MalformedURLException mue) {
						throw ce;
					}
				} else {
					throw ce;
				}
			}
		} catch(CoreException ce) {
			throw Utilities.newCoreException(NLS.bind(Messages.InternalSiteManager_UnableToAccessURL, (new String[] { url.toExternalForm() })), ce);
		}
	}
	
	private static ISite createSite(ISiteFactory factory, URL url, URL originalUrl, IProgressMonitor monitor) throws CoreException, InvalidSiteTypeException {
		
		ISite site;
			
		site = createSite(factory, url, monitor);
		httpSitesUpdatedUrls.put(originalUrl.toExternalForm(), url);	
		
		return site;
	}
	
	private static ISite createSite(ISiteFactory factory, URL url, IProgressMonitor monitor) throws CoreException, InvalidSiteTypeException {
		if (factory instanceof ISiteFactoryExtension)
			return ((ISiteFactoryExtension)factory).createSite(url, monitor);
		else
			return factory.createSite(url);
	}

	/*
	 * Creates a new site on the file system
	 * This is the only Site we can create.
	 * 
	 * @param siteLocation
	 * @throws CoreException
	 */
	public static ISite createSite(File siteLocation) throws CoreException {
		ISite site = null;
		if (siteLocation != null) {
			try {
				URL siteURL = siteLocation.toURL();
				site = getSite(siteURL, false, null);
			} catch (MalformedURLException e) {
				throw Utilities.newCoreException(NLS.bind(Messages.InternalSiteManager_UnableToCreateURL, (new String[] { siteLocation.getAbsolutePath() })), e);
			}
		}
		return site;
	}


	/**
	 * Method downloaded.
	 * @param downloadSize size downloaded in bytes
	 * @param time time in seconds
	 * @param url
	 */
	public static void downloaded(long downloadSize, long time, URL url) {
		if (downloadSize <= 0 || time < 0)
			return;
		String host = url.getHost();
		long sizeByTime = (time == 0) ? 0 : downloadSize / time;
		Long value = new Long(sizeByTime);
		if (estimates == null) {
			estimates = new HashMap();
		} else {
			Long previous = (Long) estimates.get(host);
			if (previous != null) {
				value = new Long((previous.longValue() + sizeByTime) / 2);
			}
		}
		estimates.put(host, value);
	}
	/**
	 * Method getEstimatedTransferRate rate bytes/seconds.
	 * @param host
	 * @return long
	 */
	public static long getEstimatedTransferRate(String host) {
		if (estimates == null)
			return 0;
		Long value = (Long) estimates.get(host);
		if (value == null)
			return 0;
		return value.longValue();
	}

}
