/*******************************************************************************
 * Copyright (c) 2010, 2011 Tasktop Technologies 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:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.commons.identity.core;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicReference;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.mylyn.commons.identity.core.Account;
import org.eclipse.mylyn.commons.identity.core.IIdentity;
import org.eclipse.mylyn.commons.identity.core.IProfile;
import org.eclipse.mylyn.commons.identity.core.IProfileImage;
import org.eclipse.mylyn.commons.identity.core.spi.Profile;
import org.eclipse.mylyn.commons.identity.core.spi.ProfileImage;

/**
 * @author Steffen Pingel
 */
public class Identity implements IIdentity {

	private static abstract class FutureJob<T> extends Job implements Future<T> {

		private boolean cancelled;

		private final AtomicReference<Throwable> futureException = new AtomicReference<Throwable>();

		private final AtomicReference<T> futureResult = new AtomicReference<T>();

		private final CountDownLatch resultLatch = new CountDownLatch(1);

		public FutureJob(String name) {
			super(name);
		}

		public boolean cancel(boolean mayInterruptIfRunning) {
			this.cancelled = true;
			return this.cancel();
		}

		public T get() throws InterruptedException, ExecutionException {
			resultLatch.await();
			return getFutureResult();
		}

		public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
			if (!resultLatch.await(timeout, unit)) {
				throw new TimeoutException();
			}
			return getFutureResult();
		}

		public boolean isCancelled() {
			return this.cancelled;
		}

		public boolean isDone() {
			return getResult() != null;
		}

		private T getFutureResult() throws ExecutionException {
			Throwable t = futureException.get();
			if (t != null) {
				throw new ExecutionException(t);
			}
			return futureResult.get();
		}

		protected void done() {
			if (resultLatch.getCount() > 0) {
				error(new RuntimeException());
			}
			resultLatch.countDown();
		}

		protected IStatus error(Throwable t) {
			futureException.set(t);
			resultLatch.countDown();
			if (t instanceof OperationCanceledException) {
				return Status.CANCEL_STATUS;
			}
			return Status.OK_STATUS;
		}

		protected IStatus success(T result) {
			futureResult.set(result);
			resultLatch.countDown();
			return Status.OK_STATUS;
		}

	}

	private static final class FutureResult<T> implements Future<T> {

		private final T result;

		private FutureResult(T result) {
			this.result = result;
		}

		public boolean cancel(boolean mayInterruptIfRunning) {
			return true;
		}

		public T get() throws InterruptedException, ExecutionException {
			return result;
		}

		public T get(long timeout, TimeUnit unit) throws InterruptedException, ExecutionException, TimeoutException {
			return result;
		}

		public boolean isCancelled() {
			return false;
		}

		public boolean isDone() {
			return true;
		}
	}

	private final Set<Account> accounts;

	private final UUID id;

	private List<ProfileImage> images;

	private final List<PropertyChangeListener> listeners;

	private final IdentityModel model;

	private Profile profile;

	private boolean refreshProfile;

	public Identity(IdentityModel model) {
		this.model = model;
		this.id = UUID.randomUUID();
		this.accounts = new CopyOnWriteArraySet<Account>();
		this.listeners = new CopyOnWriteArrayList<PropertyChangeListener>();
	}

	public void addAccount(Account account) {
		accounts.add(account);
		refreshProfile = true;
	}

	public void addPropertyChangeListener(PropertyChangeListener listener) {
		listeners.add(listener);
	}

	public Account[] getAccounts() {
		return accounts.toArray(new Account[accounts.size()]);
	}

	public Account getAccountById(String id) {
		if (id == null) {
			return null;
		}
		for (Account account : accounts) {
			if (id.equals(account.getId())) {
				return account;
			}
		}
		return null;
	}

	public Account getAccountByKind(String kind) {
		if (kind == null) {
			return null;
		}
		for (Account account : accounts) {
			if (kind.equals(account.getKind())) {
				return account;
			}
		}
		return null;
	}

	public String[] getAliases() {
		Set<String> aliases = new HashSet<String>(accounts.size());
		for (Account account : accounts) {
			aliases.add(account.getId());
		}
		return aliases.toArray(new String[aliases.size()]);
	}

	public UUID getId() {
		return id;
	}

	public boolean is(Account account) {
		return accounts.contains(account);
	}

	public boolean is(String id) {
		return getAccountById(id) != null;
	}

	public void removeAccount(Account account) {
		accounts.remove(account);
	}

	public void removePropertyChangeListener(PropertyChangeListener listener) {
		listeners.remove(listener);
	}

	public synchronized Future<IProfileImage> requestImage(final int preferredWidth, final int preferredHeight) {
		if (images != null) {
			for (final ProfileImage image : images) {
				if (image.getWidth() == preferredWidth && image.getHeight() == preferredHeight) {
					return new FutureResult<IProfileImage>(image);
				}
			}
		}
		FutureJob<IProfileImage> job = new FutureJob<IProfileImage>(Messages.Identity_Retrieving_Image) {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					ProfileImage image = model.getImage(Identity.this, preferredWidth, preferredHeight, monitor);
					if (image != null) {
						addImage(image);
					}
					return success(image);
				} catch (Throwable t) {
					return error(t);
				} finally {
					done();
				}
			}
		};
		job.schedule();
		return job;
	}

	public Future<IProfile> requestProfile() {
		if (profile != null && !refreshProfile) {
			return new FutureResult<IProfile>(profile);
		}

		refreshProfile = false;
		FutureJob<IProfile> job = new FutureJob<IProfile>(Messages.Identity_Retrieving_Profile) {
			@Override
			protected IStatus run(IProgressMonitor monitor) {
				try {
					Profile profile = new Profile(Identity.this);
					model.updateProfile(profile, monitor);
					setProfile(profile);
					return success(profile);
				} catch (Throwable t) {
					return error(t);
				} finally {
					done();
				}
			}
		};
		job.schedule();
		return job;
	}

	private void firePropertyChangeEvent(String propertyName, Object oldValue, Object newValue) {
		PropertyChangeEvent event = new PropertyChangeEvent(this, propertyName, oldValue, newValue);
		for (PropertyChangeListener listener : listeners) {
			listener.propertyChange(event);
		}
	}

	protected synchronized void addImage(ProfileImage image) {
		if (images == null) {
			images = new ArrayList<ProfileImage>();
		}
		images.add(image);
		firePropertyChangeEvent("image", null, image); //$NON-NLS-1$
	}

	protected synchronized void removeImage(ProfileImage image) {
		if (images != null) {
			images.remove(image);
		}
	}

	protected void setProfile(Profile profile) {
		this.profile = profile;
	}

}
