/*******************************************************************************
 * Copyright (c) 2013 Frank Becker 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:
 *     Frank Becker - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.bugzilla.rest.core;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.mylyn.commons.core.StatusHandler;
import org.eclipse.mylyn.commons.core.operations.IOperationMonitor;
import org.eclipse.mylyn.commons.core.operations.OperationUtil;
import org.eclipse.mylyn.commons.net.AuthenticationCredentials;
import org.eclipse.mylyn.commons.net.Policy;
import org.eclipse.mylyn.commons.repositories.core.RepositoryLocation;
import org.eclipse.mylyn.commons.repositories.core.auth.AuthenticationType;
import org.eclipse.mylyn.commons.repositories.core.auth.UserCredentials;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.Field;
import org.eclipse.mylyn.internal.bugzilla.rest.core.response.data.FieldValues;
import org.eclipse.mylyn.internal.commons.core.operations.NullOperationMonitor;
import org.eclipse.mylyn.internal.tasks.core.IRepositoryConstants;
import org.eclipse.mylyn.tasks.core.AbstractRepositoryConnector;
import org.eclipse.mylyn.tasks.core.IRepositoryElement;
import org.eclipse.mylyn.tasks.core.IRepositoryQuery;
import org.eclipse.mylyn.tasks.core.ITask;
import org.eclipse.mylyn.tasks.core.RepositoryInfo;
import org.eclipse.mylyn.tasks.core.RepositoryVersion;
import org.eclipse.mylyn.tasks.core.TaskRepository;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskAttachmentHandler;
import org.eclipse.mylyn.tasks.core.data.AbstractTaskDataHandler;
import org.eclipse.mylyn.tasks.core.data.TaskAttribute;
import org.eclipse.mylyn.tasks.core.data.TaskData;
import org.eclipse.mylyn.tasks.core.data.TaskDataCollector;
import org.eclipse.mylyn.tasks.core.data.TaskMapper;
import org.eclipse.mylyn.tasks.core.sync.ISynchronizationSession;

import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.UncheckedExecutionException;

public class BugzillaRestConnector extends AbstractRepositoryConnector {

	public static final Duration CLIENT_CACHE_DURATION = new Duration(24, TimeUnit.HOURS);

	public static final Duration CONFIGURATION_CACHE_EXPIRE_DURATION = new Duration(7, TimeUnit.DAYS);

	public static final Duration CONFIGURATION_CACHE_REFRESH_AFTER_WRITE_DURATION = new Duration(1, TimeUnit.DAYS);

	private static final ThreadLocal<IOperationMonitor> context = new ThreadLocal<IOperationMonitor>();

	private BugzillaRestTaskAttachmentHandler attachmentHandler;

	private boolean ignoredProperty(String propertyName) {
		if (propertyName.equals(RepositoryLocation.PROPERTY_LABEL) || propertyName.equals(TaskRepository.OFFLINE)
				|| propertyName.equals(IRepositoryConstants.PROPERTY_ENCODING)
				|| propertyName.equals(TaskRepository.PROXY_HOSTNAME) || propertyName.equals(TaskRepository.PROXY_PORT)
				|| propertyName.equals("org.eclipse.mylyn.tasklist.repositories.savePassword") //$NON-NLS-1$
				|| propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.usedefault") //$NON-NLS-1$
				|| propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.savePassword") //$NON-NLS-1$
				|| propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.username") //$NON-NLS-1$
				|| propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.password") //$NON-NLS-1$
				|| propertyName.equals("org.eclipse.mylyn.tasklist.repositories.proxy.enabled")) { //$NON-NLS-1$
			return true;
		}
		return false;
	}

	private final PropertyChangeListener repositoryChangeListener4ClientCache = new PropertyChangeListener() {

		@Override
		public void propertyChange(PropertyChangeEvent evt) {
			if (ignoredProperty(evt.getPropertyName())) {
				return;
			}
			TaskRepository taskRepository = (TaskRepository) evt.getSource();
			clientCache.invalidate(new RepositoryKey(taskRepository));
		}
	};

	private final PropertyChangeListener repositoryChangeListener4ConfigurationCache = new PropertyChangeListener() {

		@Override
		public void propertyChange(PropertyChangeEvent evt) {
			if (ignoredProperty(evt.getPropertyName())
					|| evt.getPropertyName().equals("org.eclipse.mylyn.tasklist.repositories.password")) { //$NON-NLS-1$
				return;
			}
			TaskRepository taskRepository = (TaskRepository) evt.getSource();
			configurationCache.invalidate(new RepositoryKey(taskRepository));
		}
	};

	private final LoadingCache<RepositoryKey, BugzillaRestClient> clientCache = CacheBuilder.newBuilder()
			.expireAfterAccess(CLIENT_CACHE_DURATION.getValue(), CLIENT_CACHE_DURATION.getUnit())
			.build(new CacheLoader<RepositoryKey, BugzillaRestClient>() {

				@Override
				public BugzillaRestClient load(RepositoryKey key) throws Exception {
					TaskRepository repository = key.getRepository();
					repository.addChangeListener(repositoryChangeListener4ClientCache);
					return createClient(repository);
				}
			});

	private final LoadingCache<RepositoryKey, Optional<BugzillaRestConfiguration>> configurationCache;

	public BugzillaRestConnector() {
		this(CONFIGURATION_CACHE_REFRESH_AFTER_WRITE_DURATION);
	}

	public BugzillaRestConnector(Duration refreshAfterWriteDuration) {
		super();
		this.attachmentHandler = new BugzillaRestTaskAttachmentHandler(this);
		configurationCache = createCacheBuilder(CONFIGURATION_CACHE_EXPIRE_DURATION, refreshAfterWriteDuration)
				.build(new CacheLoader<RepositoryKey, Optional<BugzillaRestConfiguration>>() {

					@Override
					public Optional<BugzillaRestConfiguration> load(RepositoryKey key) throws Exception {
						BugzillaRestClient client = clientCache.get(key);
						TaskRepository repository = key.getRepository();
						repository.addChangeListener(repositoryChangeListener4ConfigurationCache);
						return Optional.fromNullable(client.getConfiguration(key.getRepository(), context.get()));
					}

					@Override
					public ListenableFuture<Optional<BugzillaRestConfiguration>> reload(final RepositoryKey key,
							Optional<BugzillaRestConfiguration> oldValue) throws Exception {
						// asynchronous!
						ListenableFutureJob<Optional<BugzillaRestConfiguration>> job = new ListenableFutureJob<Optional<BugzillaRestConfiguration>>(
								"") {

							@Override
							protected IStatus run(IProgressMonitor monitor) {
								BugzillaRestClient client;
								try {
									client = clientCache.get(key);
									set(Optional
											.fromNullable(client.getConfiguration(key.getRepository(), context.get())));
								} catch (ExecutionException e) {
									e.printStackTrace();
									return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN,
											"BugzillaRestConnector reload Configuration", e);
								}
								return Status.OK_STATUS;
							}
						};
						job.schedule();
						return job;
					}
				});
	}

	protected CacheBuilder<Object, Object> createCacheBuilder(Duration expireAfterWriteDuration,
			Duration refreshAfterWriteDuration) {
		return CacheBuilder.newBuilder()
				.expireAfterWrite(expireAfterWriteDuration.getValue(), expireAfterWriteDuration.getUnit())
				.refreshAfterWrite(refreshAfterWriteDuration.getValue(), refreshAfterWriteDuration.getUnit());
	}

	@Override
	public boolean canCreateNewTask(TaskRepository repository) {
		return true;
	}

	@Override
	public boolean canCreateTaskFromKey(TaskRepository repository) {
		// ignore
		return false;
	}

	@Override
	public String getConnectorKind() {
		return BugzillaRestCore.CONNECTOR_KIND;
	}

	@Override
	public String getLabel() {
		return "Bugzilla 5.0 or later with REST";
	}

	@Override
	public String getRepositoryUrlFromTaskUrl(String taskUrl) {
		if (taskUrl == null) {
			return null;
		}
		int index = taskUrl.indexOf("/rest.cgi/"); //$NON-NLS-1$
		return index == -1 ? null : taskUrl.substring(0, index);
	}

	@Override
	public TaskData getTaskData(TaskRepository repository, String taskIdOrKey, IProgressMonitor monitor)
			throws CoreException {
		return ((BugzillaRestTaskDataHandler) getTaskDataHandler()).getTaskData(repository, taskIdOrKey, monitor);
	}

	@Override
	public String getTaskIdFromTaskUrl(String taskUrl) {
		// ignore
		return null;
	}

	@Override
	public String getTaskUrl(String repositoryUrl, String taskIdOrKey) {
		return repositoryUrl + "/rest.cgi/bug/" + taskIdOrKey; //$NON-NLS-1$
	}

	@Override
	public boolean hasTaskChanged(TaskRepository taskRepository, ITask task, TaskData taskData) {
		String lastKnownLocalModValue = task
				.getAttribute(BugzillaRestTaskSchema.getDefault().DATE_MODIFICATION.getKey());
		TaskAttribute latestRemoteModAttribute = taskData.getRoot().getMappedAttribute(TaskAttribute.DATE_MODIFICATION);
		String latestRemoteModValue = latestRemoteModAttribute != null ? latestRemoteModAttribute.getValue() : null;
		return !Objects.equal(latestRemoteModValue, lastKnownLocalModValue);
	}

	@Override
	public IStatus performQuery(TaskRepository repository, IRepositoryQuery query, TaskDataCollector collector,
			ISynchronizationSession session, IProgressMonitor monitor) {
		monitor = Policy.monitorFor(monitor);
		try {
			monitor.beginTask("performQuery", IProgressMonitor.UNKNOWN);
			BugzillaRestClient client = getClient(repository);
			IOperationMonitor progress = OperationUtil.convert(monitor, "performQuery", 3); //$NON-NLS-1$
			return client.performQuery(repository, query, collector, progress);
		} catch (CoreException e) {
			return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, IStatus.INFO,
					"CoreException from performQuery", e);
		} catch (BugzillaRestException e) {
			return new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, IStatus.INFO,
					"BugzillaRestException from performQuery", e);
		} finally {
			monitor.done();
		}
	}

	@Override
	public void updateRepositoryConfiguration(TaskRepository taskRepository, IProgressMonitor monitor)
			throws CoreException {
		context.set(monitor != null ? OperationUtil.convert(monitor) : new NullOperationMonitor());
		configurationCache.refresh(new RepositoryKey(taskRepository));
		context.remove();
	}

	@Override
	public void updateTaskFromTaskData(TaskRepository taskRepository, ITask task, TaskData taskData) {
		TaskMapper scheme = getTaskMapping(taskData);
		scheme.applyTo(task);
		task.setUrl(taskData.getRepositoryUrl() + "/rest.cgi/bug/" + taskData.getTaskId()); //$NON-NLS-1$

		boolean isComplete = false;
		TaskAttribute attributeStatus = taskData.getRoot().getMappedAttribute(TaskAttribute.STATUS);
		if (attributeStatus != null) {
			try {
				BugzillaRestConfiguration configuration;
				configuration = getRepositoryConfiguration(taskRepository);
				if (configuration != null) {
					Field stat = configuration.getFieldWithName(IBugzillaRestConstants.BUG_STATUS);
					for (FieldValues fieldValue : stat.getValues()) {
						if (attributeStatus.getValue().equals(fieldValue.getName())) {
							isComplete = !fieldValue.isOpen();
						}
					}
				}
			} catch (CoreException e) {
				StatusHandler.log(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN,
						"Error during get BugzillaRestConfiguration", e));
			}
		}
		if (taskData.isPartial()) {
			if (isComplete) {
				if (task.getCompletionDate() == null) {
					task.setCompletionDate(new Date(0));
				}
			} else {
				task.setCompletionDate(null);
			}
		} else {
			inferCompletionDate(task, taskData, scheme, isComplete);
		}

	}

	private void inferCompletionDate(ITask task, TaskData taskData, TaskMapper scheme, boolean isComplete) {
		if (isComplete) {
			Date completionDate = null;
			List<TaskAttribute> taskComments = taskData.getAttributeMapper().getAttributesByType(taskData,
					TaskAttribute.TYPE_COMMENT);
			if (taskComments != null && taskComments.size() > 0) {
				TaskAttribute lastComment = taskComments.get(taskComments.size() - 1);
				if (lastComment != null) {
					TaskAttribute attributeCommentDate = lastComment.getMappedAttribute(TaskAttribute.COMMENT_DATE);
					if (attributeCommentDate != null) {
						completionDate = new Date(Long.parseLong(attributeCommentDate.getValue()));
					}
				}
			}
			if (completionDate == null) {
				// Use last modified date
				TaskAttribute attributeLastModified = taskData.getRoot()
						.getMappedAttribute(TaskAttribute.DATE_MODIFICATION);
				if (attributeLastModified != null && attributeLastModified.getValue().length() > 0) {
					completionDate = taskData.getAttributeMapper().getDateValue(attributeLastModified);
				}
			}
			task.setCompletionDate(completionDate);
		} else {
			task.setCompletionDate(null);
		}
		// Bugzilla Specific Attributes

		// Product
		if (scheme.getProduct() != null) {
			task.setAttribute(BugzillaRestTaskSchema.getDefault().PRODUCT.getKey(), scheme.getProduct());
		}

		// Severity
		TaskAttribute attrSeverity = taskData.getRoot()
				.getMappedAttribute(BugzillaRestTaskSchema.getDefault().SEVERITY.getKey());
		if (attrSeverity != null && !attrSeverity.getValue().equals("")) { //$NON-NLS-1$
			task.setAttribute(BugzillaRestTaskSchema.getDefault().SEVERITY.getKey(), attrSeverity.getValue());
		}

		// Severity
		TaskAttribute attrDelta = taskData.getRoot()
				.getAttribute(BugzillaRestTaskSchema.getDefault().DATE_MODIFICATION.getKey());
		if (attrDelta != null && !attrDelta.getValue().equals("")) { //$NON-NLS-1$
			task.setAttribute(BugzillaRestTaskSchema.getDefault().DATE_MODIFICATION.getKey(), attrDelta.getValue());
		}
	}

	@Override
	public AbstractTaskDataHandler getTaskDataHandler() {
		return new BugzillaRestTaskDataHandler(this);
	}

	private BugzillaRestClient createClient(TaskRepository repository) {
		RepositoryLocation location = new RepositoryLocation(convertProperties(repository));
		AuthenticationCredentials credentials1 = repository
				.getCredentials(org.eclipse.mylyn.commons.net.AuthenticationType.REPOSITORY);
		UserCredentials credentials = new UserCredentials(credentials1.getUserName(), credentials1.getPassword(), null,
				true);
		location.setCredentials(AuthenticationType.REPOSITORY, credentials);
		BugzillaRestClient client = new BugzillaRestClient(location, this);

		return client;
	}

	private Map<String, String> convertProperties(TaskRepository repository) {
		return repository.getProperties().entrySet().stream().collect(
				Collectors.toMap(e -> convertProperty(e.getKey()), Map.Entry::getValue));
	}

	@SuppressWarnings("restriction")
	private String convertProperty(String key) {
		if (TaskRepository.PROXY_USEDEFAULT.equals(key)) {
			return RepositoryLocation.PROPERTY_PROXY_USEDEFAULT;
		} else if (TaskRepository.PROXY_HOSTNAME.equals(key)) {
			return RepositoryLocation.PROPERTY_PROXY_HOST;
		} else if (TaskRepository.PROXY_PORT.equals(key)) {
			return RepositoryLocation.PROPERTY_PROXY_PORT;
		}
		return key;
	}

	/**
	 * Returns the Client for the {@link TaskRepository}.
	 *
	 * @param repository
	 *            the {@link TaskRepository} object
	 * @return the client Object
	 * @throws CoreException
	 */
	public BugzillaRestClient getClient(TaskRepository repository) throws CoreException {
		try {
			return clientCache.get(new RepositoryKey(repository));
		} catch (ExecutionException e) {
			throw new CoreException(
					new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, "TaskRepositoryManager is null"));
		}
	}

	@Override
	public RepositoryInfo validateRepository(TaskRepository repository, IProgressMonitor monitor) throws CoreException {
		try {
			BugzillaRestClient client = createClient(repository);
			if (!client.validate(OperationUtil.convert(monitor))) {
				throw new CoreException(
						new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, "repository is invalide"));
			}
			BugzillaRestVersion version = client.getVersion(OperationUtil.convert(monitor));
			return new RepositoryInfo(new RepositoryVersion(version.toString()));
		} catch (Exception e) {
			throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e));
		}
	}

	public BugzillaRestConfiguration getRepositoryConfiguration(TaskRepository repository) throws CoreException {
		if (clientCache.getIfPresent(new RepositoryKey(repository)) == null) {
			getClient(repository);
		}
		try {
			Optional<BugzillaRestConfiguration> configurationOptional = configurationCache
					.get(new RepositoryKey(repository));
			return configurationOptional.isPresent() ? configurationOptional.get() : null;
		} catch (UncheckedExecutionException e) {
			throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e));
		} catch (ExecutionException e) {
			throw new CoreException(new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, e.getMessage(), e));
		}
	}

	public void clearClientCache() {
		clientCache.invalidateAll();
	}

	public void clearConfigurationCache() {
		configurationCache.invalidateAll();
	}

	public void clearAllCaches() {
		clearClientCache();
		clearConfigurationCache();
	}

	@Override
	public boolean isRepositoryConfigurationStale(TaskRepository repository, IProgressMonitor monitor)
			throws CoreException {
		return false;
	}

	@Override
	public TaskMapper getTaskMapping(final TaskData taskData) {

		return new TaskMapper(taskData) {
			@Override
			public String getTaskKey() {
				TaskAttribute attribute = getTaskData().getRoot()
						.getAttribute(BugzillaRestTaskSchema.getDefault().BUG_ID.getKey());
				if (attribute != null) {
					return attribute.getValue();
				}
				return super.getTaskKey();
			}

			@Override
			public String getTaskKind() {
				return taskData.getConnectorKind();
			}

			@Override
			public String getTaskUrl() {
				return taskData.getRepositoryUrl();
			}
		};
	}

	@Override
	@Nullable
	public AbstractTaskAttachmentHandler getTaskAttachmentHandler() {
		return attachmentHandler;
	}

	@Override
	@Nullable
	public URL getAuthenticatedUrl(@NonNull TaskRepository repository, @NonNull IRepositoryElement element) {
		if (element instanceof ITask) {
			try {
				String url = element.getUrl();
				String urlString = url.replace("/rest.cgi/bug/", "/show_bug.cgi?id="); //$NON-NLS-1$ //$NON-NLS-2$
				return new URL(urlString);
			} catch (MalformedURLException e) {
				StatusHandler.log(
						new Status(IStatus.ERROR, BugzillaRestCore.ID_PLUGIN, "could not create url from string", e)); //$NON-NLS-1$
			}
		}
		return super.getAuthenticatedUrl(repository, element);
	}

}
