/*******************************************************************************
 * Copyright (c) 2004, 2015 Tasktop Technologies and others.
 * 
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * https://www.eclipse.org/legal/epl-2.0
 * 
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 *     Tasktop Technologies - initial API and implementation
 *******************************************************************************/

package org.eclipse.mylyn.internal.tasks.core;

import java.util.Collections;
import java.util.Date;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;

import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.mylyn.tasks.core.IRepositoryElement;
import org.eclipse.mylyn.tasks.core.ITask;

/**
 * Encapsulates tasks that reside on a repository or local computer and participate in synchronization with the source
 * that contains their data.
 * 
 * @author Mik Kersten
 * @author Rob Elves
 * @since 2.0
 */
public abstract class AbstractTask extends AbstractTaskContainer implements ITask, ITaskRepositoryElement {

	public static final String DEFAULT_TASK_KIND = "task"; //$NON-NLS-1$

	private String repositoryUrl;

	private String taskKind = DEFAULT_TASK_KIND;

	private final String taskId;

	private String owner;

	private boolean active = false;

	private String summary;

	private String priority = PriorityLevel.getDefault().toString();

	private boolean isNotifiedIncoming = false;

	private boolean reminded = false;

	private final Set<AbstractTaskContainer> containers = new CopyOnWriteArraySet<AbstractTaskContainer>();

	// ************ Synch ****************

	/** The last time this task's bug report was in a synchronized (read?) state. */
	private String lastReadTimeStamp;

	private boolean synchronizing;

	private boolean submitting;

	private SynchronizationState synchronizationState = SynchronizationState.SYNCHRONIZED;

	// transient
	private IStatus status = null;

	private boolean stale = false;

	private Date completionDate = null;

	private Date creationDate = null;

	private Date modificationDate = null;

	private DateRange scheduledForDate = null;

	private Date dueDate = null;

	private String notes = ""; //$NON-NLS-1$

	private int estimatedTimeHours = 0;

	private boolean markReadPending;

	// TODO 4.0 make private
	protected String taskKey;

	private AttributeMap attributeMap;

	private boolean changed;

	private String ownerId;

	public AbstractTask(String repositoryUrl, String taskId, String summary) {
		super(RepositoryTaskHandleUtil.getHandle(repositoryUrl, taskId));
		this.repositoryUrl = repositoryUrl;
		this.taskId = taskId;
		this.summary = summary;
	}

	/**
	 * Final to preserve the handle identifier format required by the framework.
	 */
	@Override
	public final String getHandleIdentifier() {
		return super.getHandleIdentifier();
	}

	/**
	 * True for tasks that can be modified without a round-trip to a server. For example, such a task can be marked
	 * completed via the Task List.
	 * 
	 * @deprecated use <code>task instanceof LocalTask</code> instead
	 */
	@Deprecated
	public abstract boolean isLocal();

	public abstract String getConnectorKind();

	@Deprecated
	public String getLastReadTimeStamp() {
		return lastReadTimeStamp;
	}

	@Deprecated
	public void setLastReadTimeStamp(String lastReadTimeStamp) {
		this.lastReadTimeStamp = (lastReadTimeStamp != null) ? lastReadTimeStamp.intern() : null;
	}

	/**
	 * @since 3.0
	 */
	public void setSynchronizationState(SynchronizationState syncState) {
		Assert.isNotNull(syncState);
		this.synchronizationState = syncState;
	}

	/**
	 * @since 3.0
	 */
	public SynchronizationState getSynchronizationState() {
		return synchronizationState;
	}

	public boolean isSynchronizing() {
		return synchronizing;
	}

	public void setSynchronizing(boolean sychronizing) {
		this.synchronizing = sychronizing;
	}

	public boolean isNotified() {
		return isNotifiedIncoming;
	}

	public void setNotified(boolean notified) {
		isNotifiedIncoming = notified;
	}

	public String getOwner() {
		return owner;
	}

	public void setOwner(String owner) {
		if (!areEqual(this.owner, owner)) {
			String oldValue = this.owner;
			this.owner = (owner != null) ? owner.intern() : null;
			firePropertyChange("owner", oldValue, owner); //$NON-NLS-1$
		}
	}

	public String getOwnerId() {
		return ownerId;
	}

	public void setOwnerId(String ownerId) {
		if (!areEqual(this.ownerId, ownerId)) {
			String oldValue = this.ownerId;
			this.ownerId = (ownerId != null) ? ownerId.intern() : null;
			firePropertyChange("ownerId", oldValue, ownerId); //$NON-NLS-1$
		}
	}

	/**
	 * Return the status, such as an error or warning, associated with this task.
	 */
	public IStatus getStatus() {
		return status;
	}

	public void setStatus(IStatus status) {
		this.status = status;
	}

	public final String getTaskId() {
		return taskId;
	}

	public final String getRepositoryUrl() {
		return repositoryUrl;
	}

	@Override
	public final void setHandleIdentifier(String handleIdentifier) {
		throw new RuntimeException("Cannot set the handle identifier of a task, set repository URL instead."); //$NON-NLS-1$
	}

	public final void setRepositoryUrl(String repositoryUrl) {
		this.repositoryUrl = (repositoryUrl != null) ? repositoryUrl.intern() : null;
		super.setHandleIdentifier(RepositoryTaskHandleUtil.getHandle(repositoryUrl, taskId));
	}

	/**
	 * User identifiable key for the task to be used in UI facilities such as label displays and hyperlinked references.
	 * Can return the same as the ID (e.g. in the case of Bugzilla). Can return null if no such label exists.
	 */
	public String getTaskKey() {
		return (taskKey == null) ? taskId : taskKey;
	}

	@Deprecated
	public boolean isSubmitting() {
		return submitting;
	}

	@Deprecated
	public void setSubmitting(boolean submitting) {
		this.submitting = submitting;
	}

	@Override
	public String toString() {
		String taskKey = getTaskKey();
		if (taskKey != null) {
			return taskKey + ": " + summary; //$NON-NLS-1$
		} else {
			return summary;
		}
	}

	public void setActive(boolean active) {
		this.active = active;
	}

	public boolean isActive() {
		return active;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj instanceof AbstractTask) {
			return this.getHandleIdentifier().equals(((ITask) obj).getHandleIdentifier());
		} else {
			return false;
		}
	}

	@Override
	public int hashCode() {
		return taskId.hashCode();
	}

	public boolean isCompleted() {
		return completionDate != null;
	}

	/**
	 * @deprecated use setCompletionDate()
	 */
	@Deprecated
	public void setCompleted(boolean completed) {
		if (completed) {
			completionDate = new Date();
		} else {
			completionDate = null;
		}
	}

	@Override
	public String getPriority() {
		return priority;
	}

	public void setPriority(String priority) {
		if (!areEqual(this.priority, priority)) {
			String oldValue = this.priority;
			this.priority = (priority != null) ? priority.intern() : null;
			firePropertyChange("priority", oldValue, priority); //$NON-NLS-1$
		}
	}

	public String getNotes() {
		// TODO: removed check for null once xml updated.
		if (notes == null) {
			notes = ""; //$NON-NLS-1$
		}
		return notes;
	}

	public void setNotes(String notes) {
		this.notes = notes;
	}

	/**
	 * @deprecated Use {@link #getEstimatedTimeHours()} instead
	 */
	@Deprecated
	public int getEstimateTimeHours() {
		return getEstimatedTimeHours();
	}

	public int getEstimatedTimeHours() {
		return estimatedTimeHours;
	}

	public void setEstimatedTimeHours(int estimated) {
		this.estimatedTimeHours = estimated;
	}

	void addParentContainer(AbstractTaskContainer container) {
		containers.add(container);
	}

	void removeParentContainer(AbstractTaskContainer container) {
		containers.remove(container);
	}

	public Set<AbstractTaskContainer> getParentContainers() {
		//return new HashSet<AbstractTaskContainer>(containers);
		return containers;
	}

	@Override
	public String getSummary() {
		return summary;
	}

	public Date getCompletionDate() {
		return completionDate;
	}

	public void setScheduledForDate(DateRange reminderDate) {
		scheduledForDate = reminderDate;
	}

	public DateRange getScheduledForDate() {
		return scheduledForDate;
	}

	public boolean isReminded() {
		return reminded;
	}

	public void setReminded(boolean reminded) {
		this.reminded = reminded;
	}

	public Date getCreationDate() {
		return creationDate;
	}

	public void setCreationDate(Date creationDate) {
		if (!areEqual(this.creationDate, creationDate)) {
			Date oldValue = this.creationDate;
			this.creationDate = creationDate;
			firePropertyChange("creationDate", oldValue, creationDate); //$NON-NLS-1$
		}
	}

	public void setSummary(String summary) {
		Assert.isNotNull(summary);
		if (!areEqual(this.summary, summary)) {
			String oldValue = this.summary;
			this.summary = summary;
			firePropertyChange("summary", oldValue, summary); //$NON-NLS-1$
		}
	}

	public void setCompletionDate(Date completionDate) {
		if (!areEqual(this.completionDate, completionDate)) {
			Date oldValue = this.completionDate;
			this.completionDate = completionDate;
			firePropertyChange("completionDate", oldValue, completionDate); //$NON-NLS-1$
		}
	}

	private boolean areEqual(Object oldValue, Object newValue) {
		return (oldValue != null) ? oldValue.equals(newValue) : oldValue == newValue;
	}

	private void firePropertyChange(String key, Object oldValue, Object newValue) {
//			PropertyChangeEvent event = new PropertyChangeEvent(this, key, oldValue, newValue);
//			for (PropertyChangeListener listener : propertyChangeListeners) {
//				listener.propertyChange(event);
//			}
		changed = true;
	}

	public boolean isChanged() {
		return changed;
	}

	public void setChanged(boolean changed) {
		this.changed = changed;
	}

	/**
	 * @deprecated use {@link TaskActivityManager#isPastReminder(AbstractTask)} instead
	 */
	@Deprecated
	public boolean isPastReminder() {
		if (isCompleted() || scheduledForDate == null || !(getScheduledForDate() instanceof DayDateRange)) {
			return false;
		} else {
			if (/*!internalIsFloatingScheduledDate() && */scheduledForDate.getEndDate().compareTo(
					TaskActivityUtil.getCalendar()) < 0) {
				return true;
			} else {
				return false;
			}
		}
	}

	public String getTaskKind() {
		return taskKind;
	}

	public void setTaskKind(String taskKind) {
		if (!areEqual(this.taskKind, taskKind)) {
			String oldValue = this.taskKind;
			this.taskKind = (taskKind != null) ? taskKind.intern() : null;
			firePropertyChange("taskKind", oldValue, taskKind); //$NON-NLS-1$
		}
	}

	@Override
	public int compareTo(IRepositoryElement taskListElement) {
		return summary.compareTo(((AbstractTask) taskListElement).summary);
	}

	public Date getDueDate() {
		return dueDate;
	}

	public void setDueDate(Date date) {
		if (!areEqual(this.dueDate, date)) {
			Date oldValue = this.dueDate;
			this.dueDate = date;
			firePropertyChange("dueDate", oldValue, date); //$NON-NLS-1$
		}
	}

	@Deprecated
	public boolean isStale() {
		return stale;
	}

	@Deprecated
	public void setStale(boolean stale) {
		this.stale = stale;
	}

	public Date getModificationDate() {
		return modificationDate;
	}

	public void setModificationDate(Date modificationDate) {
		if (!areEqual(this.modificationDate, modificationDate)) {
			Date oldValue = this.modificationDate;
			this.modificationDate = modificationDate;
			firePropertyChange("modificationDate", oldValue, modificationDate); //$NON-NLS-1$
		}
	}

	public boolean isMarkReadPending() {
		return markReadPending;
	}

	public void setMarkReadPending(boolean markReadPending) {
		this.markReadPending = markReadPending;
	}

	public void setTaskKey(String taskKey) {
		if (!areEqual(this.taskKey, taskKey)) {
			String oldValue = this.taskKey;
			this.taskKey = taskKey;
			firePropertyChange("taskKey", oldValue, taskKey); //$NON-NLS-1$
		}
	}

	public synchronized String getAttribute(String key) {
		return (attributeMap != null) ? attributeMap.getAttribute(key) : null;
	}

	public synchronized Map<String, String> getAttributes() {
		if (attributeMap != null) {
			return attributeMap.getAttributes();
		} else {
			return Collections.emptyMap();
		}
	}

	public void setAttribute(String key, String value) {
		String oldValue;
		synchronized (this) {
			if (attributeMap == null) {
				attributeMap = new AttributeMap();
			}
			oldValue = attributeMap.getAttribute(key);
			if (!areEqual(oldValue, value)) {
				attributeMap.setAttribute(key, value);
			} else {
				return;
			}
		}
		firePropertyChange(key, oldValue, value);
	}

	@Override
	public void setUrl(String url) {
		String oldValue = getUrl();
		if (!areEqual(oldValue, url)) {
			super.setUrl(url);
			firePropertyChange("url", oldValue, url); //$NON-NLS-1$
		}
	}

}
