/*********************************************************************
 * Copyright (c) 2010, 2014 Sony Ericsson/ST Ericsson 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:
 *      Sony Ericsson/ST Ericsson - initial API and implementation
 *      Tasktop Technologies - improvements
 *      GitHub, Inc. - fixes for bug 354753
 *      Sascha Scholz (SAP) - improvements
 *      Marc-Andre Laperle (Ericsson) - Add topic
 *********************************************************************/
package org.eclipse.mylyn.internal.gerrit.core;

import java.util.Date;
import java.util.Map;
import java.util.Set;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.mylyn.internal.gerrit.core.client.GerritChange;
import org.eclipse.mylyn.internal.gerrit.core.client.GerritClient;
import org.eclipse.mylyn.internal.gerrit.core.client.GerritConfiguration;
import org.eclipse.mylyn.internal.gerrit.core.client.GerritException;
import org.eclipse.mylyn.internal.gerrit.core.client.compat.ChangeDetailX;
import org.eclipse.mylyn.internal.gerrit.core.client.data.GerritPerson;
import org.eclipse.mylyn.internal.gerrit.core.client.data.GerritQueryResult;
import org.eclipse.mylyn.internal.gerrit.core.client.rest.GerritReviewLabel;
import org.eclipse.mylyn.internal.gerrit.core.remote.GerritRemoteFactoryProvider;
import org.eclipse.mylyn.reviews.core.model.IRepository;
import org.eclipse.mylyn.reviews.core.model.IReview;
import org.eclipse.mylyn.reviews.core.spi.remote.emf.RemoteEmfConsumer;
import org.eclipse.mylyn.reviews.core.spi.remote.emf.RemoteEmfObserver;
import org.eclipse.mylyn.tasks.core.IRepositoryPerson;
import org.eclipse.mylyn.tasks.core.ITaskMapping;
import org.eclipse.mylyn.tasks.core.RepositoryResponse;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskSchema.Field;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskAttributeMapper;
import org.eclipse.mylyn.tasks.core.data.TaskCommentMapper;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.osgi.util.NLS;

import com.google.gerrit.common.data.AccountInfo;
import com.google.gerrit.common.data.ApprovalDetail;
import com.google.gerrit.common.data.ChangeDetail;
import com.google.gerrit.common.data.ChangeInfo;
import com.google.gerrit.reviewdb.Account;
import com.google.gerrit.reviewdb.ApprovalCategory;
import com.google.gerrit.reviewdb.Change;
import com.google.gerrit.reviewdb.ChangeMessage;
import com.google.gerrit.reviewdb.PatchSetApproval;
import com.google.gerrit.reviewdb.Project;

/**
 * @author Mikael Kober
 * @author Thomas Westling
 * @author Steffen Pingel
 * @author Kevin Sawicki
 */
public class GerritTaskDataHandler extends AbstractTaskDataHandler {

	private final GerritConnector connector;

	private final String ANONYMOUS = "Anonymous"; //$NON-NLS-1$

	public GerritTaskDataHandler(GerritConnector connector) {
		this.connector = connector;
	}

	public TaskData createTaskData(TaskRepository repository, String taskId, IProgressMonitor monitor) {
		TaskData data = new TaskData(getAttributeMapper(repository), GerritConnector.CONNECTOR_KIND,
				repository.getRepositoryUrl(), taskId);
		initializeTaskData(repository, data, null, monitor);
		return data;
	}

	public TaskData createPartialTaskData(TaskRepository repository, String taskId, IProgressMonitor monitor) {
		TaskData data = new TaskData(getAttributeMapper(repository), GerritConnector.CONNECTOR_KIND,
				repository.getRepositoryUrl(), taskId);
		GerritQueryResultSchema.getDefault().initialize(data);
		data.setPartial(true);
		return data;
	}

	@Override
	public TaskAttributeMapper getAttributeMapper(TaskRepository repository) {
		return new TaskAttributeMapper(repository);
	}

	/**
	 * Retrieves task data for the given review from repository.
	 */
	public TaskData getTaskData(TaskRepository repository, String taskId, IProgressMonitor monitor)
			throws CoreException {
		ReviewObserver reviewObserver = new ReviewObserver();
		try {
			GerritClient client = connector.getClient(repository);
			boolean anonymous = client.isAnonymous();
			String id = null;
			if (!anonymous) {
				id = getAccountId(client, repository, monitor);
			}
			taskId = client.toReviewId(taskId, monitor);
			TaskData taskData = createTaskData(repository, taskId, monitor);

			RemoteEmfConsumer<IRepository, IReview, String, GerritChange, String, Date> consumer = updateModelData(
					repository, taskData, reviewObserver, monitor);
			GerritChange gerritChange = consumer.getRemoteObject();
			if (gerritChange == null) {
				throw new CoreException(connector.createErrorStatus(repository,
						NLS.bind("Couldn't retrieve remote object for task: {0}. Check remote connection", taskId))); //$NON-NLS-1$
			}
			Project.NameKey project = gerritChange.getChangeDetail().getChange().getProject();
			client.refreshConfigOnce(project, monitor);
			if (!monitor.isCanceled()) {
				updateTaskData(repository, taskData, gerritChange, !anonymous, id);
			}
			return taskData;
		} catch (GerritException e) {
			throw connector.toCoreException(repository,
					NLS.bind("Problem retrieving task data for task: {0}", taskId), e); //$NON-NLS-1$
		} finally {
			reviewObserver.dispose();
		}
	}

	private RemoteEmfConsumer<IRepository, IReview, String, GerritChange, String, Date> updateModelData(
			TaskRepository repository, TaskData taskData, ReviewObserver reviewObserver, IProgressMonitor monitor)
			throws CoreException {
		GerritClient client = connector.getClient(repository);
		GerritRemoteFactoryProvider factoryProvider = (GerritRemoteFactoryProvider) client.getFactoryProvider();
		RemoteEmfConsumer<IRepository, IReview, String, GerritChange, String, Date> consumer = factoryProvider.getReviewFactory()
				.getConsumerForLocalKey(factoryProvider.getRoot(), taskData.getTaskId());

		consumer.addObserver(reviewObserver);
		if (!consumer.isRetrieving()) {
			if (monitor.isCanceled()) {
				return consumer;
			}
			consumer.open();
			if (monitor.isCanceled()) {
				return consumer;
			}
			consumer.setAsynchronous(false);
			consumer.retrieve(true);
			consumer.setAsynchronous(true);
		}

		while (!reviewObserver.complete && !monitor.isCanceled()) {
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				reviewObserver.dispose();
				Thread.currentThread().interrupt();
			}
		}

		consumer.save();
		if (!consumer.getStatus().isOK()) {
			if (consumer.getStatus().getException() instanceof CoreException) {
				throw ((CoreException) consumer.getStatus().getException());
			}
			throw new CoreException(consumer.getStatus());
		}
		return consumer;
	}

	private class ReviewObserver extends RemoteEmfObserver<IRepository, IReview, String, Date> {
		boolean complete;

		@Override
		public void updated(boolean modified) {
			complete = true;
		}
	}

	/**
	 * Get account id for repository
	 * 
	 * @param client
	 * @param repository
	 * @param monitor
	 * @return account id or null if not found
	 * @throws GerritException
	 */
	protected String getAccountId(GerritClient client, TaskRepository repository, IProgressMonitor monitor)
			throws GerritException {
		String id = repository.getProperty(GerritConnector.KEY_REPOSITORY_ACCOUNT_ID);
		if (id == null) {
			Account account = client.getAccount(monitor);
			if (account != null) {
				id = account.getId().toString();
				repository.setProperty(GerritConnector.KEY_REPOSITORY_ACCOUNT_ID, id);
			}
		}
		return id;
	}

	@Override
	public boolean initializeTaskData(TaskRepository repository, TaskData taskData, ITaskMapping initializationData,
			IProgressMonitor monitor) {
		GerritTaskSchema.getDefault().initialize(taskData);
		return true;
	}

	@Override
	public RepositoryResponse postTaskData(TaskRepository repository, TaskData taskData,
			Set<TaskAttribute> oldAttributes, IProgressMonitor monitor) throws CoreException {
		throw new UnsupportedOperationException();
	}

	public void updateTaskData(TaskRepository repository, TaskData data, GerritChange gerritReview, boolean canPublish,
			String accountId) {
		GerritTaskSchema schema = GerritTaskSchema.getDefault();

		ChangeDetail changeDetail = gerritReview.getChangeDetail();
		Change change = changeDetail.getChange();
		AccountInfo owner = changeDetail.getAccounts().get(change.getOwner());

		updatePartialTaskData(repository, data, new GerritQueryResult(new ChangeInfo(change)));
		setAttributeValue(data, schema.BRANCH, change.getDest().get());
		String userId = GerritUtil.getUserId(owner);
		String userLabel = GerritUtil.getUserLabel(owner);
		TaskAttribute ownerAttribute = setAttributeValue(data, schema.OWNER, userId);
		if (ownerAttribute != null) {
			ownerAttribute.putOption(userId, userLabel);
		}
		setAttributeValue(data, schema.UPLOADED, dateToString(((ChangeDetailX) changeDetail).getDateCreated()));
		setAttributeValue(data, schema.UPDATED, dateToString(((ChangeDetailX) changeDetail).getLastModified()));
		setAttributeValue(data, schema.DESCRIPTION, changeDetail.getDescription());
		int i = 1;
		String accountName = repository.getUserName();
		for (ChangeMessage message : changeDetail.getMessages()) {
			TaskCommentMapper mapper = new TaskCommentMapper();
			if (message.getAuthor() != null) {
				AccountInfo author = changeDetail.getAccounts().get(message.getAuthor());
				String userName;
				String id = author.getId().toString();
				if (id.equals(accountId) && accountName != null) {
					userName = accountName;
				} else {
					String email = author.getPreferredEmail();
					userName = (email != null) ? email : id;
				}
				IRepositoryPerson person = repository.createPerson(userName);
				person.setName(author.getFullName());
				mapper.setAuthor(person);
			} else {
				// messages without an author are from Gerrit itself
				IRepositoryPerson person = repository.createPerson("Gerrit Code Review"); //$NON-NLS-1$
				mapper.setAuthor(person);
			}
			mapper.setText(message.getMessage());
			mapper.setCreationDate(message.getWrittenOn());
			mapper.setNumber(i);
			TaskAttribute attribute = data.getRoot().createAttribute(TaskAttribute.PREFIX_COMMENT + i);
			mapper.applyTo(attribute);
			i++;
		}

		setAttributeValue(data, schema.CAN_PUBLISH, Boolean.toString(canPublish));

		// Retrieve the 'starred' state
		setAttributeValue(data, schema.IS_STARRED, Boolean.toString(changeDetail.isStarred()));

		// Retrieve the approvals
		Short reviewState = 0;
		Short verifyState = 0;
		for (ApprovalDetail approvals : changeDetail.getApprovals()) {
			Map<ApprovalCategory.Id, PatchSetApproval> map = approvals.getApprovalMap();
			PatchSetApproval approval = map.get(new ApprovalCategory.Id("CRVW")); //$NON-NLS-1$
			if (approval != null) {
				reviewState = getStateValue(approval.getValue(), reviewState);
			}
			approval = map.get(new ApprovalCategory.Id("VRIF")); //$NON-NLS-1$
			if (approval != null) {
				verifyState = getStateValue(approval.getValue(), verifyState);
			}
		}
		setAttributeValue(data, schema.REVIEW_STATE, reviewState.toString());
		setAttributeValue(data, schema.VERIFY_STATE, verifyState.toString());
	}

	private Short getStateValue(Short value, Short oldState) {
		Short state = 0;
		if (value < 0) {
			state = (short) Math.min(oldState, value);
		} else {
			state = (short) Math.max(oldState, value);
		}
		return state;
	}

	@Override
	public void migrateTaskData(TaskRepository repository, TaskData taskData) {
		super.migrateTaskData(repository, taskData);
		//Support 1.1.0 commenting capability see https://bugs.eclipse.org/bugs/show_bug.cgi?id=344108
		if (taskData.getRoot().getAttribute(GerritTaskSchema.getDefault().NEW_COMMENT.getKey()) == null) {
			taskData.getRoot().createAttribute(GerritTaskSchema.getDefault().NEW_COMMENT.getKey());
		}
	}

	public void updatePartialTaskData(TaskRepository repository, TaskData data, GerritQueryResult queryResult) {
		GerritQueryResultSchema schema = GerritQueryResultSchema.getDefault();
		setAttributeValue(data, schema.KEY, shortenChangeId(queryResult.getId()));
		setAttributeValue(data, schema.PROJECT, queryResult.getProject());
		setAttributeValue(data, schema.SUMMARY, queryResult.getSubject());
		setAttributeValue(data, schema.STATUS, queryResult.getStatus());
		setAttributeValue(data, schema.URL, connector.getTaskUrl(repository.getUrl(), data.getTaskId()));
		setAttributeValue(data, schema.UPDATED, dateToString(queryResult.getUpdated()));
		setAttributeValue(data, schema.CHANGE_ID, queryResult.getId());
		if (GerritConnector.isClosed(queryResult.getStatus())) {
			setAttributeValue(data, schema.COMPLETED, dateToString(queryResult.getUpdated()));
		}

		GerritPerson owner = queryResult.getOwner();
		if (owner != null) {
			String fullName = getFullNameFromAccount(repository);
			if (fullName != null && fullName.equals(owner.getName())) {
				// populate ITask.ownerId so that My Tasks filter works 
				String preferredEmail = getPreferredEmailFromAccount(repository);
				TaskAttribute ownerAttribute = setAttributeValue(data, schema.OWNER, preferredEmail);
				ownerAttribute.putOption(preferredEmail, fullName);
			} else {
				// we don't have the owner id and it could be expensive to include it in the query results
				setAttributeValue(data, schema.OWNER, owner.getName());
			}
		} else {
			setAttributeValue(data, schema.OWNER, ANONYMOUS);
		}
		setAttributeValue(data, schema.BRANCH, queryResult.getBranch());
		setAttributeValue(data, schema.IS_STARRED, (queryResult.isStarred() ? Boolean.TRUE : Boolean.FALSE).toString());
		setAttributeValue(data, schema.TOPIC, queryResult.getTopic());

		GerritReviewLabel reviewLabel = queryResult.getReviewLabel();
		if (reviewLabel != null) {
			if (reviewLabel.getVerifyStatus() != null) {
				setAttributeValue(data, schema.VERIFY_STATE, reviewLabel.getVerifyStatus().getStatus());
			}
			if (reviewLabel.getCodeReviewStatus() != null) {
				setAttributeValue(data, schema.REVIEW_STATE, reviewLabel.getCodeReviewStatus().getStatus());
			}
		}
	}

	private String getFullNameFromAccount(TaskRepository repository) {
		GerritConfiguration config = connector.getConfiguration(repository);
		if (config != null && config.getAccount() != null) {
			return config.getAccount().getFullName();
		}
		return null;
	}

	private String getPreferredEmailFromAccount(TaskRepository repository) {
		GerritConfiguration config = connector.getConfiguration(repository);
		if (config != null && config.getAccount() != null) {
			return config.getAccount().getPreferredEmail();
		}
		return null;
	}

	private String shortenChangeId(String changeId) {
		changeId = GerritUtil.toChangeId(changeId);
		return changeId.substring(0, Math.min(9, changeId.length()));
	}

	/**
	 * Convenience method to set the value of a given Attribute in the given {@link TaskData}.
	 */
	private TaskAttribute setAttributeValue(TaskData data, Field gerritAttribute, String value) {
		TaskAttribute attribute = data.getRoot().getAttribute(gerritAttribute.getKey());
		if (value != null) {
			attribute.setValue(value);
		}
		return attribute;
	}

	private static String dateToString(Date date) {
		if (date == null) {
			return ""; //$NON-NLS-1$
		} else {
			return Long.toString(date.getTime());
		}
	}

}
