/*******************************************************************************
 * Copyright (c) 2000, 2015 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * 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 void clearCharsetGenerationCount() {
		charsetAndContentId = getContentId();
	}

	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);
	}
}
