/*
 * 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.notes;

import static org.eclipse.jgit.lib.FileMode.TREE;

import java.io.IOException;
import java.util.Iterator;
import java.util.NoSuchElementException;

import org.eclipse.jgit.lib.AbbreviatedObjectId;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.MutableObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.ObjectReader;
import org.eclipse.jgit.lib.TreeFormatter;

/**
 * A note tree holding only note subtrees, each named using a 2 digit hex name.
 *
 * The fanout buckets/trees contain on average 256 subtrees, naming the subtrees
 * by a slice of the ObjectId contained within them, from "00" through "ff".
 *
 * Each fanout bucket has a {@link #prefixLen} that defines how many digits it
 * skips in an ObjectId before it gets to the digits matching {@link #table}.
 *
 * The root tree has {@code prefixLen == 0}, and thus does not skip any digits.
 * For ObjectId "c0ffee...", the note (if it exists) will be stored within the
 * bucket {@code table[0xc0]}.
 *
 * The first level tree has {@code prefixLen == 2}, and thus skips the first two
 * digits. For the same example "c0ffee..." object, its note would be found
 * within the {@code table[0xff]} bucket (as first 2 digits "c0" are skipped).
 *
 * Each subtree is loaded on-demand, reducing startup latency for reads that
 * only need to examine a few objects. However, due to the rather uniform
 * distribution of the SHA-1 hash that is used for ObjectIds, accessing 256
 * objects is very likely to load all of the subtrees into memory.
 *
 * A FanoutBucket must be parsed from a tree object by {@link NoteParser}.
 */
class FanoutBucket extends InMemoryNoteBucket {
	/**
	 * Fan-out table similar to the PackIndex structure.
	 *
	 * Notes for an object are stored within the sub-bucket that is held here as
	 * {@code table[ objectId.getByte( prefixLen / 2 ) ]}. If the slot is null
	 * there are no notes with that prefix.
	 */
	private final NoteBucket[] table;

	/** Number of non-null slots in {@link #table}. */
	private int cnt;

	FanoutBucket(int prefixLen) {
		super(prefixLen);
		table = new NoteBucket[256];
	}

	void setBucket(int cell, ObjectId id) {
		table[cell] = new LazyNoteBucket(id);
		cnt++;
	}

	void setBucket(int cell, InMemoryNoteBucket bucket) {
		table[cell] = bucket;
		cnt++;
	}

	@Override
	Note getNote(AnyObjectId objId, ObjectReader or) throws IOException {
		NoteBucket b = table[cell(objId)];
		return b != null ? b.getNote(objId, or) : null;

	}

	NoteBucket getBucket(int cell) {
		return table[cell];
	}

	static InMemoryNoteBucket loadIfLazy(NoteBucket b, AnyObjectId prefix,
			ObjectReader or) throws IOException {
		if (b == null)
			return null;
		if (b instanceof InMemoryNoteBucket)
			return (InMemoryNoteBucket) b;
		return ((LazyNoteBucket) b).load(prefix, or);
	}

	@Override
	Iterator<Note> iterator(AnyObjectId objId, final ObjectReader reader)
			throws IOException {
		final MutableObjectId id = new MutableObjectId();
		id.fromObjectId(objId);

		return new Iterator<>() {
			private int cell;

			private Iterator<Note> itr;

			@Override
			public boolean hasNext() {
				if (itr != null && itr.hasNext())
					return true;

				for (; cell < table.length; cell++) {
					NoteBucket b = table[cell];
					if (b == null)
						continue;

					try {
						id.setByte(prefixLen >> 1, cell);
						itr = b.iterator(id, reader);
					} catch (IOException err) {
						throw new RuntimeException(err);
					}

					if (itr.hasNext()) {
						cell++;
						return true;
					}
				}
				return false;
			}

			@Override
			public Note next() {
				if (hasNext()) {
					return itr.next();
				}
				throw new NoSuchElementException();
			}

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

	@Override
	int estimateSize(AnyObjectId noteOn, ObjectReader or) throws IOException {
		// If most of this fan-out is full, estimate it should still be split.
		if (LeafBucket.MAX_SIZE * 3 / 4 <= cnt)
			return 1 + LeafBucket.MAX_SIZE;

		// Due to the uniform distribution of ObjectIds, having less nodes full
		// indicates a good chance the total number of children below here
		// is less than the MAX_SIZE split point. Get a more accurate count.

		MutableObjectId id = new MutableObjectId();
		id.fromObjectId(noteOn);

		int sz = 0;
		for (int cell = 0; cell < 256; cell++) {
			NoteBucket b = table[cell];
			if (b == null)
				continue;

			id.setByte(prefixLen >> 1, cell);
			sz += b.estimateSize(id, or);
			if (LeafBucket.MAX_SIZE < sz)
				break;
		}
		return sz;
	}

	@Override
	InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
			ObjectReader or) throws IOException {
		int cell = cell(noteOn);
		NoteBucket b = table[cell];

		if (b == null) {
			if (noteData == null) {
				return this;
			}

			LeafBucket n = new LeafBucket(prefixLen + 2);
			table[cell] = n.set(noteOn, noteData, or);
			cnt++;
			return this;

		}
		NoteBucket n = b.set(noteOn, noteData, or);
		if (n == null) {
			table[cell] = null;
			cnt--;

			if (cnt == 0) {
				return null;
			}

			return contractIfTooSmall(noteOn, or);

		} else if (n != b) {
			table[cell] = n;
		}
		return this;
	}

	InMemoryNoteBucket contractIfTooSmall(AnyObjectId noteOn, ObjectReader or)
			throws IOException {
		if (estimateSize(noteOn, or) < LeafBucket.MAX_SIZE) {
			// We are small enough to just contract to a single leaf.
			InMemoryNoteBucket r = new LeafBucket(prefixLen);
			for (Iterator<Note> i = iterator(noteOn, or); i.hasNext();)
				r = r.append(i.next());
			r.nonNotes = nonNotes;
			return r;
		}

		return this;
	}

	private static final byte[] hexchar = { '0', '1', '2', '3', '4', '5', '6',
			'7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };

	@Override
	ObjectId writeTree(ObjectInserter inserter) throws IOException {
		return inserter.insert(build(true, inserter));
	}

	@Override
	ObjectId getTreeId() {
		try (ObjectInserter.Formatter f = new ObjectInserter.Formatter()) {
			return f.idFor(build(false, null));
		} catch (IOException e) {
			// should never happen as we are not inserting
			throw new RuntimeException(e);
		}
	}

	private TreeFormatter build(boolean insert, ObjectInserter inserter)
			throws IOException {
		byte[] nameBuf = new byte[2];
		TreeFormatter fmt = new TreeFormatter(treeSize());
		NonNoteEntry e = nonNotes;

		for (int cell = 0; cell < 256; cell++) {
			NoteBucket b = table[cell];
			if (b == null)
				continue;

			nameBuf[0] = hexchar[cell >>> 4];
			nameBuf[1] = hexchar[cell & 0x0f];

			while (e != null && e.pathCompare(nameBuf, 0, 2, TREE) < 0) {
				e.format(fmt);
				e = e.next;
			}

			ObjectId id;
			if (insert) {
				id = b.writeTree(inserter);
			} else {
				id = b.getTreeId();
			}
			fmt.append(nameBuf, 0, 2, TREE, id);
		}

		for (; e != null; e = e.next)
			e.format(fmt);
		return fmt;
	}

	private int treeSize() {
		int sz = cnt * TreeFormatter.entrySize(TREE, 2);
		for (NonNoteEntry e = nonNotes; e != null; e = e.next)
			sz += e.treeEntrySize();
		return sz;
	}

	@Override
	InMemoryNoteBucket append(Note note) {
		int cell = cell(note);
		InMemoryNoteBucket b = (InMemoryNoteBucket) table[cell];

		if (b == null) {
			LeafBucket n = new LeafBucket(prefixLen + 2);
			table[cell] = n.append(note);
			cnt++;

		} else {
			InMemoryNoteBucket n = b.append(note);
			if (n != b)
				table[cell] = n;
		}
		return this;
	}

	private int cell(AnyObjectId id) {
		return id.getByte(prefixLen >> 1);
	}

	private class LazyNoteBucket extends NoteBucket {
		private final ObjectId treeId;

		LazyNoteBucket(ObjectId treeId) {
			this.treeId = treeId;
		}

		@Override
		Note getNote(AnyObjectId objId, ObjectReader or) throws IOException {
			return load(objId, or).getNote(objId, or);
		}

		@Override
		Iterator<Note> iterator(AnyObjectId objId, ObjectReader reader)
				throws IOException {
			return load(objId, reader).iterator(objId, reader);
		}

		@Override
		int estimateSize(AnyObjectId objId, ObjectReader or) throws IOException {
			return load(objId, or).estimateSize(objId, or);
		}

		@Override
		InMemoryNoteBucket set(AnyObjectId noteOn, AnyObjectId noteData,
				ObjectReader or) throws IOException {
			return load(noteOn, or).set(noteOn, noteData, or);
		}

		@Override
		ObjectId writeTree(ObjectInserter inserter) {
			return treeId;
		}

		@Override
		ObjectId getTreeId() {
			return treeId;
		}

		private InMemoryNoteBucket load(AnyObjectId prefix, ObjectReader or)
				throws IOException {
			AbbreviatedObjectId p = prefix.abbreviate(prefixLen + 2);
			InMemoryNoteBucket self = NoteParser.parse(p, treeId, or);
			table[cell(prefix)] = self;
			return self;
		}
	}
}
