/*
 * Copyright (C) 2017, Google Inc.
 * and other copyright owners as documented in the project's IP log.
 *
 * This program and the accompanying materials are made available
 * under the terms of the Eclipse Distribution License v1.0 which
 * accompanies this distribution, is reproduced below, and is
 * available at http://www.eclipse.org/org/documents/edl-v10.php
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or
 * without modification, are permitted provided that the following
 * conditions are met:
 *
 * - Redistributions of source code must retain the above copyright
 *   notice, this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above
 *   copyright notice, this list of conditions and the following
 *   disclaimer in the documentation and/or other materials provided
 *   with the distribution.
 *
 * - Neither the name of the Eclipse Foundation, Inc. nor the
 *   names of its contributors may be used to endorse or promote
 *   products derived from this software without specific prior
 *   written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

package org.eclipse.jgit.pgm.debug;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import org.eclipse.jgit.internal.storage.io.BlockSource;
import org.eclipse.jgit.internal.storage.reftable.RefCursor;
import org.eclipse.jgit.internal.storage.reftable.ReftableReader;
import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.lib.RefComparator;
import org.eclipse.jgit.lib.TextProgressMonitor;
import org.eclipse.jgit.pgm.Command;
import org.eclipse.jgit.pgm.TextBuiltin;
import org.kohsuke.args4j.Argument;

@Command
class VerifyReftable extends TextBuiltin {
	private static final long SEED1 = 0xaba8bb4de4caf86cL;
	private static final long SEED2 = 0x28bb5c25ad43ecb5L;

	@Argument(index = 0)
	private String lsRemotePath;

	@Argument(index = 1)
	private String reftablePath;

	/** {@inheritDoc} */
	@Override
	protected void run() throws Exception {
		List<Ref> refs = WriteReftable.readRefs(lsRemotePath);

		try (FileInputStream in = new FileInputStream(reftablePath);
				BlockSource src = BlockSource.from(in);
				ReftableReader reader = new ReftableReader(src)) {
			scan(refs, reader);
			seek(refs, reader);
			byId(refs, reader);
		}
	}

	@SuppressWarnings("nls")
	private void scan(List<Ref> refs, ReftableReader reader)
			throws IOException {
		errw.print(String.format("%-20s", "sequential scan..."));
		errw.flush();
		try (RefCursor rc = reader.allRefs()) {
			for (Ref exp : refs) {
				verify(exp, rc);
			}
			if (rc.next()) {
				throw die("expected end of table");
			}
		}
		errw.println(" OK");
	}

	@SuppressWarnings("nls")
	private void seek(List<Ref> refs, ReftableReader reader)
			throws IOException {
		List<Ref> rnd = new ArrayList<>(refs);
		Collections.shuffle(rnd, new Random(SEED1));

		TextProgressMonitor pm = new TextProgressMonitor(errw);
		pm.beginTask("random seek", rnd.size());
		for (Ref exp : rnd) {
			try (RefCursor rc = reader.seekRef(exp.getName())) {
				verify(exp, rc);
				if (rc.next()) {
					throw die("should not have ref after " + exp.getName());
				}
			}
			pm.update(1);
		}
		pm.endTask();
	}

	@SuppressWarnings("nls")
	private void byId(List<Ref> refs, ReftableReader reader)
			throws IOException {
		Map<ObjectId, List<Ref>> want = groupById(refs);
		List<List<Ref>> rnd = new ArrayList<>(want.values());
		Collections.shuffle(rnd, new Random(SEED2));

		TextProgressMonitor pm = new TextProgressMonitor(errw);
		pm.beginTask("byObjectId", rnd.size());
		for (List<Ref> exp : rnd) {
			Collections.sort(exp, RefComparator.INSTANCE);
			ObjectId id = exp.get(0).getObjectId();
			try (RefCursor rc = reader.byObjectId(id)) {
				for (Ref r : exp) {
					verify(r, rc);
				}
			}
			pm.update(1);
		}
		pm.endTask();
	}

	private static Map<ObjectId, List<Ref>> groupById(List<Ref> refs) {
		Map<ObjectId, List<Ref>> m = new HashMap<>();
		for (Ref r : refs) {
			ObjectId id = r.getObjectId();
			if (id != null) {
				List<Ref> c = m.get(id);
				if (c == null) {
					c = new ArrayList<>(2);
					m.put(id, c);
				}
				c.add(r);
			}
		}
		return m;
	}

	@SuppressWarnings("nls")
	private void verify(Ref exp, RefCursor rc) throws IOException {
		if (!rc.next()) {
			throw die("ended before " + exp.getName());
		}

		Ref act = rc.getRef();
		if (!exp.getName().equals(act.getName())) {
			throw die(String.format("expected %s, found %s",
					exp.getName(),
					act.getName()));
		}

		if (exp.isSymbolic()) {
			if (!act.isSymbolic()) {
				throw die("expected " + act.getName() + " to be symbolic");
			}
			if (!exp.getTarget().getName().equals(act.getTarget().getName())) {
				throw die(String.format("expected %s to be %s, found %s",
						exp.getName(),
						exp.getLeaf().getName(),
						act.getLeaf().getName()));
			}
			return;
		}

		if (!AnyObjectId.isEqual(exp.getObjectId(), act.getObjectId())) {
			throw die(String.format("expected %s to be %s, found %s",
					exp.getName(),
					id(exp.getObjectId()),
					id(act.getObjectId())));
		}

		if (exp.getPeeledObjectId() != null
				&& !AnyObjectId.isEqual(exp.getPeeledObjectId(),
						act.getPeeledObjectId())) {
			throw die(String.format("expected %s to be %s, found %s",
					exp.getName(),
					id(exp.getPeeledObjectId()),
					id(act.getPeeledObjectId())));
		}
	}

	@SuppressWarnings("nls")
	private static String id(ObjectId id) {
		return id != null ? id.name() : "<null>";
	}
}
