/*******************************************************************************
 * Copyright (c) 2004, 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
 *     James Blackburn (Broadcom Corp.) - ongoing development
 *******************************************************************************/
package org.eclipse.core.internal.localstore;

import java.io.*;
import java.util.Arrays;
import java.util.Comparator;
import org.eclipse.core.internal.utils.UniversalUniqueIdentifier;
import org.eclipse.core.runtime.IPath;

public class HistoryBucket extends Bucket {

	/**
	 * A entry in the bucket index. Each entry has one path and a collection
	 * of states, which by their turn contain a (UUID, timestamp) pair.
	 * <p>
	 * This class is intended as a lightweight way of hiding the internal data structure.
	 * Objects of this class are supposed to be short-lived. No instances
	 * of this class are kept stored anywhere. The real stuff (the internal data structure)
	 * is.
	 * </p>
	 */
	public static final class HistoryEntry extends Bucket.Entry {

		final static Comparator<byte[]> COMPARATOR = (state1, state2) -> compareStates(state1, state2);

		// the length of each component of the data array
		private final static byte[][] EMPTY_DATA = new byte[0][];
		// the length of a long in bytes
		private final static int LONG_LENGTH = 8;
		// the length of a UUID in bytes
		private final static int UUID_LENGTH = UniversalUniqueIdentifier.BYTES_SIZE;
		public final static int DATA_LENGTH = UUID_LENGTH + LONG_LENGTH;

		/**
		 * The history states. The first array dimension is the number of states. The
		 * second dimension is an encoding of the {UUID,timestamp} pair for that entry.
		 */
		private byte[][] data;

		/**
		 * Comparison logic for states in byte[] form.
		 *
		 * @see Comparator#compare(java.lang.Object, java.lang.Object)
		 */
		static int compareStates(byte[] state1, byte[] state2) {
			long timestamp1 = getTimestamp(state1);
			long timestamp2 = getTimestamp(state2);
			if (timestamp1 == timestamp2)
				return -UniversalUniqueIdentifier.compareTime(state1, state2);
			return timestamp1 < timestamp2 ? +1 : -1;
		}

		/**
		 * Returns the byte array representation of a (UUID, timestamp) pair.
		 */
		static byte[] getState(UniversalUniqueIdentifier uuid, long timestamp) {
			byte[] uuidBytes = uuid.toBytes();
			byte[] state = new byte[DATA_LENGTH];
			System.arraycopy(uuidBytes, 0, state, 0, uuidBytes.length);
			for (int j = 0; j < LONG_LENGTH; j++) {
				state[UUID_LENGTH + j] = (byte) (0xFF & timestamp);
				timestamp >>>= 8;
			}
			return state;
		}

		private static long getTimestamp(byte[] state) {
			long timestamp = 0;
			for (int j = 0; j < LONG_LENGTH; j++)
				timestamp += (state[UUID_LENGTH + j] & 0xFFL) << j * 8;
			return timestamp;
		}

		/**
		 * Inserts the given item into the given array at the right position.
		 * Returns the resulting array. Returns null if the item already exists.
		 */
		static byte[][] insert(byte[][] existing, byte[] toAdd) {
			// look for the right spot where to insert the new guy
			int index = search(existing, toAdd);
			if (index >= 0)
				// already there - nothing else to be done
				return null;
			// not found - insert
			int insertPosition = -index - 1;
			byte[][] newValue = new byte[existing.length + 1][];
			if (insertPosition > 0)
				System.arraycopy(existing, 0, newValue, 0, insertPosition);
			newValue[insertPosition] = toAdd;
			if (insertPosition < existing.length)
				System.arraycopy(existing, insertPosition, newValue, insertPosition + 1, existing.length - insertPosition);
			return newValue;
		}

		/**
		 * Merges two entries (are always sorted). Duplicates are discarded.
		 */
		static byte[][] merge(byte[][] base, byte[][] additions) {
			int additionPointer = 0;
			int basePointer = 0;
			int added = 0;
			byte[][] result = new byte[base.length + additions.length][];
			while (basePointer < base.length && additionPointer < additions.length) {
				int comparison = compareStates(base[basePointer], additions[additionPointer]);
				if (comparison == 0) {
					result[added++] = base[basePointer++];
					// duplicate, ignore
					additionPointer++;
				} else if (comparison < 0)
					result[added++] = base[basePointer++];
				else
					result[added++] = additions[additionPointer++];
			}
			// copy the remaining states from either additions or base arrays
			byte[][] remaining = basePointer == base.length ? additions : base;
			int remainingPointer = basePointer == base.length ? additionPointer : basePointer;
			int remainingCount = remaining.length - remainingPointer;
			System.arraycopy(remaining, remainingPointer, result, added, remainingCount);
			added += remainingCount;
			if (added == base.length + additions.length)
				// no collisions
				return result;
			// there were collisions, need to compact
			byte[][] finalResult = new byte[added][];
			System.arraycopy(result, 0, finalResult, 0, finalResult.length);
			return finalResult;
		}

		private static int search(byte[][] existing, byte[] element) {
			return Arrays.binarySearch(existing, element, COMPARATOR);
		}

		public HistoryEntry(IPath path, byte[][] data) {
			super(path);
			this.data = data;
		}

		public HistoryEntry(IPath path, HistoryEntry base) {
			super(path);
			this.data = new byte[base.data.length][];
			System.arraycopy(base.data, 0, this.data, 0, this.data.length);
		}

		/**
		 * Compacts the data array removing any null slots. If non-null slots
		 * are found, the entry is marked for removal.
		 */
		private void compact() {
			if (!isDirty())
				return;
			int occurrences = 0;
			for (byte[] d : data) {
				if (d != null) {
					data[occurrences++] = d;
				}
			}
			if (occurrences == data.length)
				// no states deleted
				return;
			if (occurrences == 0) {
				// no states remaining
				data = EMPTY_DATA;
				delete();
				return;
			}
			byte[][] result = new byte[occurrences][];
			System.arraycopy(data, 0, result, 0, occurrences);
			data = result;
		}

		public void deleteOccurrence(int i) {
			markDirty();
			data[i] = null;
		}

		byte[][] getData() {
			return data;
		}

		@Override
		public int getOccurrences() {
			return data.length;
		}

		public long getTimestamp(int i) {
			return getTimestamp(data[i]);
		}

		public UniversalUniqueIdentifier getUUID(int i) {
			return new UniversalUniqueIdentifier(data[i]);
		}

		@Override
		public Object getValue() {
			return data;
		}

		@Override
		public boolean isEmpty() {
			return data.length == 0;
		}

		@Override
		public void visited() {
			compact();
		}

	}

	/**
	 * Version number for the current implementation file's format.
	 * <p>
	 * Version 2 (3.1 M5):
	 * </p>
	 * <pre>
	 * FILE ::= VERSION_ID ENTRY+
	 * ENTRY ::= PATH STATE_COUNT STATE+
	 * PATH ::= string (does not include project name)
	 * STATE_COUNT ::= int
	 * STATE ::= UUID LAST_MODIFIED
	 * UUID	 ::= byte[16]
	 * LAST_MODIFIED ::= byte[8]
	 * </pre>
	 * <p>
	 * Version 1 (3.1 M4):
	 * </p>
	 * <pre>
	 * FILE ::= VERSION_ID ENTRY+
	 * ENTRY ::= PATH STATE_COUNT STATE+
	 * PATH ::= string
	 * STATE_COUNT ::= int
	 * STATE ::= UUID LAST_MODIFIED
	 * UUID	 ::= byte[16]
	 * LAST_MODIFIED ::= byte[8]
	 * </pre>
	 */
	public final static byte VERSION = 2;

	public HistoryBucket() {
		super();
	}

	public void addBlob(IPath path, UniversalUniqueIdentifier uuid, long lastModified) {
		byte[] state = HistoryEntry.getState(uuid, lastModified);
		String pathAsString = path.toString();
		byte[][] existing = (byte[][]) getEntryValue(pathAsString);
		if (existing == null) {
			setEntryValue(pathAsString, new byte[][] {state});
			return;
		}
		byte[][] newValue = HistoryEntry.insert(existing, state);
		if (newValue == null)
			return;
		setEntryValue(pathAsString, newValue);
	}

	public void addBlobs(HistoryEntry fileEntry) {
		IPath path = fileEntry.getPath();
		byte[][] additions = fileEntry.getData();
		String pathAsString = path.toString();
		byte[][] existing = (byte[][]) getEntryValue(pathAsString);
		if (existing == null) {
			setEntryValue(pathAsString, additions);
			return;
		}
		setEntryValue(pathAsString, HistoryEntry.merge(existing, additions));
	}

	@Override
	protected Bucket.Entry createEntry(IPath path, Object value) {
		return new HistoryEntry(path, (byte[][]) value);
	}

	public HistoryEntry getEntry(IPath path) {
		String pathAsString = path.toString();
		byte[][] existing = (byte[][]) getEntryValue(pathAsString);
		if (existing == null)
			return null;
		return new HistoryEntry(path, existing);
	}

	@Override
	protected String getIndexFileName() {
		return "history.index"; //$NON-NLS-1$
	}

	@Override
	protected byte getVersion() {
		return VERSION;
	}

	@Override
	protected String getVersionFileName() {
		return "history.version"; //$NON-NLS-1$
	}

	@Override
	protected Object readEntryValue(DataInputStream source) throws IOException {
		int length = source.readUnsignedShort();
		byte[][] uuids = new byte[length][HistoryEntry.DATA_LENGTH];
		for (byte[] uuid : uuids)
			source.read(uuid);
		return uuids;
	}

	@Override
	protected void writeEntryValue(DataOutputStream destination, Object entryValue) throws IOException {
		byte[][] uuids = (byte[][]) entryValue;
		destination.writeShort(uuids.length);
		for (byte[] uuid : uuids)
			destination.write(uuid);
	}
}
