/*
 * Copyright (C) 2010, Google Inc. and others
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Distribution License v. 1.0 which is available at
 * https://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

package org.eclipse.jgit.util;

import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.function.BinaryOperator;
import java.util.stream.Collector;

import org.eclipse.jgit.annotations.Nullable;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefComparator;

/**
 * Specialized variant of an ArrayList to support a {@code RefDatabase}.
 * <p>
 * This list is a hybrid of a Map&lt;String,Ref&gt; and of a List&lt;Ref&gt;. It
 * tracks reference instances by name by keeping them sorted and performing
 * binary search to locate an entry. Lookup time is O(log N), but addition and
 * removal is O(N + log N) due to the list expansion or contraction costs.
 * <p>
 * This list type is copy-on-write. Mutation methods return a new copy of the
 * list, leaving {@code this} unmodified. As a result we cannot easily implement
 * the {@link java.util.List} interface contract.
 *
 * @param <T>
 *            the type of reference being stored in the collection.
 */
public class RefList<T extends Ref> implements Iterable<Ref> {
	private static final RefList<Ref> EMPTY = new RefList<>(new Ref[0], 0);

	/**
	 * Create an empty unmodifiable reference list.
	 *
	 * @param <T>
	 *            type of reference being stored.
	 * @return an empty unmodifiable reference list.
	 */
	@SuppressWarnings("unchecked")
	public static <T extends Ref> RefList<T> emptyList() {
		return (RefList<T>) EMPTY;
	}

	final Ref[] list;

	final int cnt;

	RefList(Ref[] list, int cnt) {
		this.list = list;
		this.cnt = cnt;
	}

	/**
	 * Initialize this list to use the same backing array as another list.
	 *
	 * @param src
	 *            the source list.
	 */
	protected RefList(RefList<T> src) {
		this.list = src.list;
		this.cnt = src.cnt;
	}

	@Override
	public Iterator<Ref> iterator() {
		return new Iterator<>() {
			private int idx;

			@Override
			public boolean hasNext() {
				return idx < cnt;
			}

			@Override
			public Ref next() {
				if (idx < cnt)
					return list[idx++];
				throw new NoSuchElementException();
			}

			@Override
			public void remove() {
				throw new UnsupportedOperationException();
			}
		};
	}

	/**
	 * Cast {@code this} as an immutable, standard {@link java.util.List}.
	 *
	 * @return {@code this} as an immutable, standard {@link java.util.List}.
	 */
	public final List<Ref> asList() {
		final List<Ref> r = Arrays.asList(list).subList(0, cnt);
		return Collections.unmodifiableList(r);
	}

	/**
	 * Get number of items in this list.
	 *
	 * @return number of items in this list.
	 */
	public final int size() {
		return cnt;
	}

	/**
	 * Get if this list is empty.
	 *
	 * @return true if the size of this list is 0.
	 */
	public final boolean isEmpty() {
		return cnt == 0;
	}

	/**
	 * Locate an entry by name.
	 *
	 * @param name
	 *            the name of the reference to find.
	 * @return the index the reference is at. If the entry is not present
	 *         returns a negative value. The insertion position for the given
	 *         name can be computed from {@code -(index + 1)}.
	 */
	public final int find(String name) {
		int high = cnt;
		if (high == 0)
			return -1;
		int low = 0;
		do {
			final int mid = (low + high) >>> 1;
			final int cmp = RefComparator.compareTo(list[mid], name);
			if (cmp < 0)
				low = mid + 1;
			else if (cmp == 0)
				return mid;
			else
				high = mid;
		} while (low < high);
		return -(low + 1);
	}

	/**
	 * Determine if a reference is present.
	 *
	 * @param name
	 *            name of the reference to find.
	 * @return true if the reference is present; false if it is not.
	 */
	public final boolean contains(String name) {
		return 0 <= find(name);
	}

	/**
	 * Get a reference object by name.
	 *
	 * @param name
	 *            the name of the reference.
	 * @return the reference object; null if it does not exist in this list.
	 */
	public final T get(String name) {
		int idx = find(name);
		return 0 <= idx ? get(idx) : null;
	}

	/**
	 * Get the reference at a particular index.
	 *
	 * @param idx
	 *            the index to obtain. Must be {@code 0 <= idx < size()}.
	 * @return the reference value, never null.
	 */
	@SuppressWarnings("unchecked")
	public final T get(int idx) {
		return (T) list[idx];
	}

	/**
	 * Obtain a builder initialized with the first {@code n} elements.
	 * <p>
	 * Copies the first {@code n} elements from this list into a new builder,
	 * which can be used by the caller to add additional elements.
	 *
	 * @param n
	 *            the number of elements to copy.
	 * @return a new builder with the first {@code n} elements already added.
	 */
	public final Builder<T> copy(int n) {
		Builder<T> r = new Builder<>(Math.max(16, n));
		r.addAll(list, 0, n);
		return r;
	}

	/**
	 * Obtain a new copy of the list after changing one element.
	 * <p>
	 * This list instance is not affected by the replacement. Because this
	 * method copies the entire list, it runs in O(N) time.
	 *
	 * @param idx
	 *            index of the element to change.
	 * @param ref
	 *            the new value, must not be null.
	 * @return copy of this list, after replacing {@code idx} with {@code ref} .
	 */
	public final RefList<T> set(int idx, T ref) {
		Ref[] newList = new Ref[cnt];
		System.arraycopy(list, 0, newList, 0, cnt);
		newList[idx] = ref;
		return new RefList<>(newList, cnt);
	}

	/**
	 * Add an item at a specific index.
	 * <p>
	 * This list instance is not affected by the addition. Because this method
	 * copies the entire list, it runs in O(N) time.
	 *
	 * @param idx
	 *            position to add the item at. If negative the method assumes it
	 *            was a direct return value from {@link #find(String)} and will
	 *            adjust it to the correct position.
	 * @param ref
	 *            the new reference to insert.
	 * @return copy of this list, after making space for and adding {@code ref}.
	 */
	public final RefList<T> add(int idx, T ref) {
		if (idx < 0)
			idx = -(idx + 1);

		Ref[] newList = new Ref[cnt + 1];
		if (0 < idx)
			System.arraycopy(list, 0, newList, 0, idx);
		newList[idx] = ref;
		if (idx < cnt)
			System.arraycopy(list, idx, newList, idx + 1, cnt - idx);
		return new RefList<>(newList, cnt + 1);
	}

	/**
	 * Remove an item at a specific index.
	 * <p>
	 * This list instance is not affected by the addition. Because this method
	 * copies the entire list, it runs in O(N) time.
	 *
	 * @param idx
	 *            position to remove the item from.
	 * @return copy of this list, after making removing the item at {@code idx}.
	 */
	public final RefList<T> remove(int idx) {
		if (cnt == 1)
			return emptyList();
		Ref[] newList = new Ref[cnt - 1];
		if (0 < idx)
			System.arraycopy(list, 0, newList, 0, idx);
		if (idx + 1 < cnt)
			System.arraycopy(list, idx + 1, newList, idx, cnt - (idx + 1));
		return new RefList<>(newList, cnt - 1);
	}

	/**
	 * Store a reference, adding or replacing as necessary.
	 * <p>
	 * This list instance is not affected by the store. The correct position is
	 * determined, and the item is added if missing, or replaced if existing.
	 * Because this method copies the entire list, it runs in O(N + log N) time.
	 *
	 * @param ref
	 *            the reference to store.
	 * @return copy of this list, after performing the addition or replacement.
	 */
	public final RefList<T> put(T ref) {
		int idx = find(ref.getName());
		if (0 <= idx)
			return set(idx, ref);
		return add(idx, ref);
	}

	@Override
	public String toString() {
		StringBuilder r = new StringBuilder();
		r.append('[');
		if (cnt > 0) {
			r.append(list[0]);
			for (int i = 1; i < cnt; i++) {
				r.append(", "); //$NON-NLS-1$
				r.append(list[i]);
			}
		}
		r.append(']');
		return r.toString();
	}

	/**
	 * Create a {@link Collector} for {@link Ref}.
	 *
	 * @param <T>
	 *            type of reference being stored.
	 * @param mergeFunction
	 *            if specified the result will be sorted and deduped.
	 * @return {@link Collector} for {@link Ref}
	 * @since 5.4
	 */
	public static <T extends Ref> Collector<T, ?, RefList<T>> toRefList(
			@Nullable BinaryOperator<T> mergeFunction) {
		return Collector.of(
				() -> new Builder<>(),
				Builder<T>::add, (b1, b2) -> {
					Builder<T> b = new Builder<>();
					b.addAll(b1);
					b.addAll(b2);
					return b;
				}, (b) -> {
					if (mergeFunction != null) {
						b.sort();
						b.dedupe(mergeFunction);
					}
					return b.toRefList();
				});
	}

	/**
	 * Builder to facilitate fast construction of an immutable RefList.
	 *
	 * @param <T>
	 *            type of reference being stored.
	 */
	public static class Builder<T extends Ref> {
		private Ref[] list;

		private int size;

		/** Create an empty list ready for items to be added. */
		public Builder() {
			this(16);
		}

		/**
		 * Create an empty list with at least the specified capacity.
		 *
		 * @param capacity
		 *            the new capacity; if zero or negative, behavior is the same as
		 *            {@link #Builder()}.
		 */
		public Builder(int capacity) {
			list = new Ref[Math.max(capacity, 16)];
		}

		/**
		 * Get size
		 *
		 * @return number of items in this builder's internal collection.
		 */
		public int size() {
			return size;
		}

		/**
		 * Get the reference at a particular index.
		 *
		 * @param idx
		 *            the index to obtain. Must be {@code 0 <= idx < size()}.
		 * @return the reference value, never null.
		 */
		@SuppressWarnings("unchecked")
		public T get(int idx) {
			return (T) list[idx];
		}

		/**
		 * Remove an item at a specific index.
		 *
		 * @param idx
		 *            position to remove the item from.
		 */
		public void remove(int idx) {
			System.arraycopy(list, idx + 1, list, idx, size - (idx + 1));
			size--;
		}

		/**
		 * Add the reference to the end of the array.
		 * <p>
		 * References must be added in sort order, or the array must be sorted
		 * after additions are complete using {@link #sort()}.
		 *
		 * @param ref
		 *            reference to add
		 */
		public void add(T ref) {
			if (list.length == size) {
				Ref[] n = new Ref[size * 2];
				System.arraycopy(list, 0, n, 0, size);
				list = n;
			}
			list[size++] = ref;
		}

		/**
		 * Add all items from another builder.
		 *
		 * @param other
		 *            another builder
		 * @since 5.4
		 */
		public void addAll(Builder other) {
			addAll(other.list, 0, other.size);
		}

		/**
		 * Add all items from a source array.
		 * <p>
		 * References must be added in sort order, or the array must be sorted
		 * after additions are complete using {@link #sort()}.
		 *
		 * @param src
		 *            the source array.
		 * @param off
		 *            position within {@code src} to start copying from.
		 * @param cnt
		 *            number of items to copy from {@code src}.
		 */
		public void addAll(Ref[] src, int off, int cnt) {
			if (list.length < size + cnt) {
				Ref[] n = new Ref[Math.max(size * 2, size + cnt)];
				System.arraycopy(list, 0, n, 0, size);
				list = n;
			}
			System.arraycopy(src, off, list, size, cnt);
			size += cnt;
		}

		/**
		 * Replace a single existing element.
		 *
		 * @param idx
		 *            index, must have already been added previously.
		 * @param ref
		 *            the new reference.
		 */
		public void set(int idx, T ref) {
			list[idx] = ref;
		}

		/** Sort the list's backing array in-place. */
		public void sort() {
			Arrays.sort(list, 0, size, RefComparator.INSTANCE);
		}

		/**
		 * Dedupe the refs in place. Must be called after {@link #sort}.
		 *
		 * @param mergeFunction
		 *            function used for de-duplication
		 */
		@SuppressWarnings("unchecked")
		void dedupe(BinaryOperator<T> mergeFunction) {
			if (size == 0) {
				return;
			}
			int lastElement = 0;
			for (int i = 1; i < size; i++) {
				if (RefComparator.INSTANCE.compare(list[lastElement],
						list[i]) == 0) {
					list[lastElement] = mergeFunction
							.apply((T) list[lastElement], (T) list[i]);
				} else {
					list[lastElement + 1] = list[i];
					lastElement++;
				}
			}
			size = lastElement + 1;
			Arrays.fill(list, size, list.length, null);
		}

		/**
		 * Get unmodifiable list based on this list
		 *
		 * @return an unmodifiable list using this collection's backing array.
		 */
		public RefList<T> toRefList() {
			return new RefList<>(list, size);
		}

		@Override
		public String toString() {
			return toRefList().toString();
		}
	}
}
