/*******************************************************************************
 * Copyright (c) 2008, 2009 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 - Initial API and implementation
 *******************************************************************************/
package org.eclipse.ptp.services.core;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.PlatformObject;
import org.eclipse.ptp.services.core.messages.Messages;
import org.eclipse.ptp.services.internal.core.ServiceModelEvent;
import org.eclipse.ui.IMemento;

/**
 * An abstract base class for service provider implementations. 
 * 
 * <strong>EXPERIMENTAL</strong>. This class or interface has been added as
 * part of a work in progress. There is no guarantee that this API will work or
 * that it will remain the same. Please do not use this API without consulting
 * with the RDT team.
 * 
 * @author vkong
 *
 */
public abstract class ServiceProvider extends PlatformObject implements IServiceProvider, IServiceProviderDescriptor {
	
	private IServiceProviderDescriptor fDescriptor;
	private final HashMap<String, String> fProperties = new HashMap<String, String>();
	protected ServiceModelManager fManager = ServiceModelManager.getInstance();

	public ServiceProvider() {
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#copy()
	 */
	public IServiceProviderWorkingCopy copy() {
		return new ServiceProviderWorkingCopy(this);
	}

	// generated by eclipse
	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ServiceProvider other = (ServiceProvider) obj;
		if (fDescriptor == null) {
			if (other.fDescriptor != null)
				return false;
		} else if (!fDescriptor.equals(other.fDescriptor))
			return false;
		return true;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#getBoolean(java.lang.String, boolean)
	 */
	public boolean getBoolean(String key, boolean defaultValue) {
		String value = getString(key, null);
		boolean result = defaultValue;
		if (value != null) {
			result = Boolean.parseBoolean(value);
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#getConfigurationString()
	 */
	public String getConfigurationString() {
		return isConfigured() ? Messages.ServiceProvider_0 : Messages.ServiceProvider_1;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#getDescriptor()
	 */
	public IServiceProviderDescriptor getDescriptor() {
		return fDescriptor;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProviderDescriptor#getId()
	 */
	public String getId() {
		if (fDescriptor == null) {
			return null;
		}
		return fDescriptor.getId();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#getInt(java.lang.String, int)
	 */
	public int getInt(String key, int defaultValue) {
		String value = getString(key, null);
		int result = defaultValue;
		if (value != null) {
			try {
				result = Integer.parseInt(value);
			} catch (NumberFormatException e) {
				// Use default
			}
		}
		return result;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProviderDescriptor#getName()
	 */
	public String getName() {
		if (fDescriptor == null) {
			return null;
		}
		return fDescriptor.getName();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProviderDescriptor#getPriority()
	 */
	public Integer getPriority() {
		if (fDescriptor == null) {
			return null;
		}
		return fDescriptor.getPriority();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#getProperties()
	 */
	public Map<String, String> getProperties() {
		return Collections.unmodifiableMap(fProperties);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProviderDescriptor#getServiceId()
	 */
	public String getServiceId() {
		if (fDescriptor == null) {
			return null;
		}
		return fDescriptor.getServiceId();
	}
	
	/*
	 * (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#getString(java.lang.String, java.lang.String)
	 */
	public String getString(String key, String defaultValue)
	{
		String value = fProperties.get(key);
		if (value == null) {
			return defaultValue;
		}
		return value;
	}

	// generated by eclipse
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((fDescriptor == null) ? 0 : fDescriptor.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#keySet()
	 */
	public Set<String> keySet() {
		return fProperties.keySet();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#putBoolean(java.lang.String, boolean)
	 */
	public void putBoolean(String key, boolean value) {
		String strVal = Boolean.toString(value);
		putString(key, strVal);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#putInt(java.lang.String, int)
	 */
	public void putInt(String key, int value) {
		String strVal = Integer.toString(value);
		putString(key, strVal);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#putString(java.lang.String, java.lang.String)
	 */
	public void putString(String key, String value) {
		fProperties.put(key, value);
		fManager.notifyListeners(new ServiceModelEvent(this, IServiceModelEvent.SERVICE_PROVIDER_CHANGED, null));
	}

	/**
	 * Restores the state of this provider from the
	 * given <code>IMemento</code>.
	 * 
	 * NOTE: This should only be implemented if a provider 
	 * wishes to override the default behavior.
	 * 
	 * @param memento for restoring the provider's state.
	 */
	public void restoreState(IMemento memento) {
		fProperties.clear();
		for (String key : memento.getAttributeKeys()) {
			fProperties.put(key, memento.getString(key));
		}
		fManager.notifyListeners(new ServiceModelEvent(this, IServiceModelEvent.SERVICE_PROVIDER_CHANGED, null));
	}

	/**
	 * Saves the state of this provider in the given
	 * <code>IMemento</code>. 
	 * 
	 * NOTE: This should only be implemented if a provider  
	 * wishes to override the default behavior.
	 * 
	 * @param memento for saving the provider's state.
	 */
	public void saveState(IMemento memento) {
		for (String key : fProperties.keySet()) {
			memento.putString(key, fProperties.get(key));
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#setDescriptor(org.eclipse.ptp.services.core.IServiceProviderDescriptor)
	 */
	public void setDescriptor(IServiceProviderDescriptor descriptor) {
		this.fDescriptor = descriptor;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.ptp.services.core.IServiceProvider#setProperties(java.util.Map)
	 */
	public void setProperties(Map<String, String> properties) {
		fProperties.putAll(properties);
		fManager.notifyListeners(new ServiceModelEvent(this, IServiceModelEvent.SERVICE_PROVIDER_CHANGED, null));
	}

}
