/*******************************************************************************
 * Copyright (c) 2000, 2015 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 Corporation - initial API and implementation
 *     Oakland Software Incorporated - added getSessionProperties and getPersistentProperties
 *     James Blackburn (Broadcom Corp.) - ongoing development
 *     Lars Vogel <Lars.Vogel@vogella.com> - Bug 473427
 *******************************************************************************/
package org.eclipse.core.internal.resources;

import java.io.*;
import java.util.Map;
import org.eclipse.core.internal.localstore.FileStoreRoot;
import org.eclipse.core.internal.utils.*;
import org.eclipse.core.internal.watson.IElementTreeData;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.QualifiedName;

/**
 * A data structure containing the in-memory state of a resource in the workspace.
 */
public class ResourceInfo implements IElementTreeData, ICoreConstants, IStringPoolParticipant {
	protected static final int LOWER = 0xFFFF;
	protected static final int UPPER = 0xFFFF0000;

	/**
	 * This field stores the resource modification stamp in the lower two bytes,
	 * and the character set generation count in the higher two bytes.
	 */
	protected volatile int charsetAndContentId = 0;

	/**
	 * The file system root that this resource is stored in
	 */
	protected FileStoreRoot fileStoreRoot;

	/** Set of flags which reflect various states of the info (used, derived, ...). */
	protected int flags = 0;

	/** Local sync info */
	// thread safety: (Concurrency004)
	protected volatile long localInfo = I_NULL_SYNC_INFO;

	/**
	 * This field stores the sync info generation in the lower two bytes, and
	 * the marker generation count in the upper two bytes.
	 */
	protected volatile int markerAndSyncStamp;

	/** The collection of markers for this resource. */
	protected MarkerSet markers = null;

	/** Modification stamp */
	protected long modStamp = 0;

	/** Unique node identifier */
	// thread safety: (Concurrency004)
	protected volatile long nodeId = 0;

	/**
	 * The properties which are maintained for the lifecycle of the workspace.
	 * <p>
	 * This field is declared as the implementing class rather than the
	 * interface so we ensure that we get it right since we are making certain
	 * assumptions about the object type w.r.t. casting.
	 */
	protected ObjectMap<QualifiedName, Object> sessionProperties = null;

	/**
	 * The table of sync information.
	 * <p>
	 * This field is declared as the implementing class rather than the
	 * interface so we ensure that we get it right since we are making certain
	 * assumptions about the object type w.r.t. casting.
	 */
	protected ObjectMap<QualifiedName, Object> syncInfo = null;

	/**
	 * Returns the integer value stored in the indicated part of this info's flags.
	 */
	protected static int getBits(int flags, int mask, int start) {
		return (flags & mask) >> start;
	}

	/**
	 * Returns the type setting for this info.  Valid values are
	 * FILE, FOLDER, PROJECT,
	 */
	public static int getType(int flags) {
		return getBits(flags, M_TYPE, M_TYPE_START);
	}

	/**
	 * Returns true if all of the bits indicated by the mask are set.
	 */
	public static boolean isSet(int flags, int mask) {
		return (flags & mask) == mask;
	}

	/**
	 * Clears all of the bits indicated by the mask.
	 */
	public void clear(int mask) {
		flags &= ~mask;
	}

	public void clearModificationStamp() {
		modStamp = IResource.NULL_STAMP;
	}

	public synchronized void clearSessionProperties() {
		sessionProperties = null;
	}

	@Override
	public Object clone() {
		try {
			return super.clone();
		} catch (CloneNotSupportedException e) {
			return null; // never gets here.
		}
	}

	public int getCharsetGenerationCount() {
		return charsetAndContentId >> 16;
	}

	public int getContentId() {
		return charsetAndContentId & LOWER;
	}

	public FileStoreRoot getFileStoreRoot() {
		return fileStoreRoot;
	}

	/**
	 * Returns the set of flags for this info.
	 */
	public int getFlags() {
		return flags;
	}

	/**
	 * Gets the local-relative sync information.
	 */
	public long getLocalSyncInfo() {
		return localInfo;
	}

	/**
	 * Returns the marker generation count.
	 * The count is incremented whenever markers on the resource change.
	 */
	public int getMarkerGenerationCount() {
		return markerAndSyncStamp >> 16;
	}

	/**
	 * Returns a copy of the collection of makers on this resource.
	 * <code>null</code> is returned if there are none.
	 */
	public MarkerSet getMarkers() {
		return getMarkers(true);
	}

	/**
	 * Returns the collection of makers on this resource.
	 * <code>null</code> is returned if there are none.
	 */
	public MarkerSet getMarkers(boolean makeCopy) {
		if (markers == null)
			return null;
		return makeCopy ? (MarkerSet) markers.clone() : markers;
	}

	public long getModificationStamp() {
		return modStamp;
	}

	public long getNodeId() {
		return nodeId;
	}

	/**
	 * Returns the property store associated with this info.  The return value may be null.
	 */
	public Object getPropertyStore() {
		return null;
	}

	/**
	 * Returns a copy of the map of this resource session properties.
	 * An empty map is returned if there are none.
	 */
	@SuppressWarnings({"unchecked"})
	public Map<QualifiedName, Object> getSessionProperties() {
		// thread safety: (Concurrency001)
		ObjectMap<QualifiedName, Object> temp = sessionProperties;
		if (temp == null)
			temp = new ObjectMap<>(5);
		else
			temp = (ObjectMap<QualifiedName, Object>) sessionProperties.clone();
		return temp;
	}

	/**
	 * Returns the value of the identified session property
	 */
	public Object getSessionProperty(QualifiedName name) {
		// thread safety: (Concurrency001)
		Map<QualifiedName, Object> temp = sessionProperties;
		if (temp == null)
			return null;
		return temp.get(name);
	}

	/**
	 * The parameter to this method is the implementing class rather than the
	 * interface so we ensure that we get it right since we are making certain
	 * assumptions about the object type w.r.t. casting.
	 */
	@SuppressWarnings({"unchecked"})
	public synchronized ObjectMap<QualifiedName, Object> getSyncInfo(boolean makeCopy) {
		if (syncInfo == null)
			return null;
		return makeCopy ? (ObjectMap<QualifiedName, Object>) syncInfo.clone() : syncInfo;
	}

	public synchronized byte[] getSyncInfo(QualifiedName id, boolean makeCopy) {
		// thread safety: (Concurrency001)
		byte[] b;
		if (syncInfo == null)
			return null;
		b = (byte[]) syncInfo.get(id);
		return b == null ? null : (makeCopy ? (byte[]) b.clone() : b);
	}

	/**
	 * Returns the sync information generation count.
	 * The count is incremented whenever sync info on the resource changes.
	 */
	public int getSyncInfoGenerationCount() {
		return markerAndSyncStamp & LOWER;
	}

	/**
	 * Returns the type setting for this info.  Valid values are
	 * FILE, FOLDER, PROJECT,
	 */
	public int getType() {
		return getType(flags);
	}

	/**
	 * Increments the charset generation count.
	 * The count is incremented whenever the encoding on the resource changes.
	 */
	public void incrementCharsetGenerationCount() {
		//increment high order bits
		charsetAndContentId = ((charsetAndContentId + LOWER + 1) & UPPER) + (charsetAndContentId & LOWER);
	}

	/**
	 * Mark this resource info as having changed content
	 */
	public void incrementContentId() {
		//increment low order bits
		charsetAndContentId = (charsetAndContentId & UPPER) + ((charsetAndContentId + 1) & LOWER);
	}

	/**
	 * Increments the marker generation count.
	 * The count is incremented whenever markers on the resource change.
	 */
	public void incrementMarkerGenerationCount() {
		//increment high order bits
		markerAndSyncStamp = ((markerAndSyncStamp + LOWER + 1) & UPPER) + (markerAndSyncStamp & LOWER);
	}

	/**
	 * Change the modification stamp to indicate that this resource has changed.
	 * The exact value of the stamp doesn't matter, as long as it can be used to
	 * distinguish two arbitrary resource generations.
	 */
	public void incrementModificationStamp() {
		modStamp++;
	}

	/**
	 * Increments the sync information generation count.
	 * The count is incremented whenever sync info on the resource changes.
	 */
	public void incrementSyncInfoGenerationCount() {
		//increment low order bits
		markerAndSyncStamp = (markerAndSyncStamp & UPPER) + ((markerAndSyncStamp + 1) & LOWER);
	}

	/**
	 * Returns true if all of the bits indicated by the mask are set.
	 */
	public boolean isSet(int mask) {
		return (flags & mask) == mask;
	}

	public void readFrom(int newFlags, DataInput input) throws IOException {
		// The flags for this info are read by the visitor (flattener).
		// See Workspace.readElement().  This allows the reader to look ahead
		// and see what type of info is being loaded.
		this.flags = newFlags;
		localInfo = input.readLong();
		nodeId = input.readLong();
		charsetAndContentId = input.readInt() & LOWER;
		modStamp = input.readLong();
	}

	/**
	 * Sets all of the bits indicated by the mask.
	 */
	public void set(int mask) {
		flags |= mask;
	}

	/**
	 * Sets the value of the indicated bits to be the given value.
	 */
	protected void setBits(int mask, int start, int value) {
		int baseMask = mask >> start;
		int newValue = (value & baseMask) << start;
		// thread safety: (guarantee atomic assignment)
		int temp = flags;
		temp &= ~mask;
		temp |= newValue;
		flags = temp;
	}

	public void setFileStoreRoot(FileStoreRoot fileStoreRoot) {
		this.fileStoreRoot = fileStoreRoot;
	}

	/**
	 * Sets the flags for this info.
	 */
	protected void setFlags(int value) {
		flags = value;
	}

	/**
	 * Sets the local-relative sync information.
	 */
	public void setLocalSyncInfo(long info) {
		localInfo = info;
	}

	/**
	 * Sets the collection of makers for this resource.
	 * <code>null</code> is passed in if there are no markers.
	 */
	public void setMarkers(MarkerSet value) {
		markers = value;
	}

	/**
	 * Sets the resource modification stamp.
	 */
	public void setModificationStamp(long value) {
		this.modStamp = value;
	}

	/**
	 *
	 */
	public void setNodeId(long id) {
		nodeId = id;
		// Resource modification stamp starts from current nodeId
		// so future generations are distinguishable (bug 160728)
		if (modStamp == 0)
			modStamp = nodeId;
	}

	/**
	 * Sets the property store associated with this info.  The value may be null.
	 */
	public void setPropertyStore(Object value) {
		// needs to be implemented on subclasses
	}

	/**
	 * Sets the identified session property to the given value.  If
	 * the value is null, the property is removed.
	 */
	@SuppressWarnings({"unchecked"})
	public synchronized void setSessionProperty(QualifiedName name, Object value) {
		// thread safety: (Concurrency001)
		if (value == null) {
			if (sessionProperties == null)
				return;
			ObjectMap<QualifiedName, Object> temp = (ObjectMap<QualifiedName, Object>) sessionProperties.clone();
			temp.remove(name);
			if (temp.isEmpty())
				sessionProperties = null;
			else
				sessionProperties = temp;
		} else {
			ObjectMap<QualifiedName, Object> temp = sessionProperties;
			if (temp == null)
				temp = new ObjectMap<>(5);
			else
				temp = (ObjectMap<QualifiedName, Object>) sessionProperties.clone();
			temp.put(name, value);
			sessionProperties = temp;
		}
	}

	/**
	 * The parameter to this method is the implementing class rather than the
	 * interface so we ensure that we get it right since we are making certain
	 * assumptions about the object type w.r.t. casting.
	 */
	protected void setSyncInfo(ObjectMap<QualifiedName, Object> syncInfo) {
		this.syncInfo = syncInfo;
	}

	public synchronized void setSyncInfo(QualifiedName id, byte[] value) {
		if (value == null) {
			//delete sync info
			if (syncInfo == null)
				return;
			syncInfo.remove(id);
			if (syncInfo.isEmpty())
				syncInfo = null;
		} else {
			//add sync info
			if (syncInfo == null)
				syncInfo = new ObjectMap<>(5);
			syncInfo.put(id, value.clone());
		}
	}

	/**
	 * Sets the type for this info to the given value.  Valid values are
	 * FILE, FOLDER, PROJECT
	 */
	public void setType(int value) {
		setBits(M_TYPE, M_TYPE_START, value);
	}

	/* (non-Javadoc
	 * Method declared on IStringPoolParticipant
	 */
	@Override
	public void shareStrings(StringPool set) {
		ObjectMap<QualifiedName, Object> map = syncInfo;
		if (map != null)
			map.shareStrings(set);
		map = sessionProperties;
		if (map != null)
			map.shareStrings(set);
		MarkerSet markerSet = markers;
		if (markerSet != null)
			markerSet.shareStrings(set);
	}

	public void writeTo(DataOutput output) throws IOException {
		// The flags for this info are written by the visitor (flattener).
		// See SaveManager.writeElement().  This allows the reader to look ahead
		// and see what type of info is being loaded.
		output.writeLong(localInfo);
		output.writeLong(nodeId);
		output.writeInt(getContentId());
		output.writeLong(modStamp);
	}
}
