/*******************************************************************************
 * Copyright (c) 2015, 2016 Google, Inc and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *   Stefan Xenos (Google) - Initial implementation
 *******************************************************************************/
package org.eclipse.jdt.internal.core.nd.java;

import java.io.File;
import java.util.List;

import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jdt.internal.core.nd.Nd;
import org.eclipse.jdt.internal.core.nd.NdNode;
import org.eclipse.jdt.internal.core.nd.NdNodeTypeRegistry;
import org.eclipse.jdt.internal.core.nd.db.ChunkCache;
import org.eclipse.jdt.internal.core.nd.db.Database;
import org.eclipse.jdt.internal.core.nd.field.FieldSearchIndex;
import org.eclipse.jdt.internal.core.nd.field.FieldSearchIndex.IResultRank;
import org.eclipse.jdt.internal.core.nd.field.FieldSearchIndex.SearchCriteria;
import org.eclipse.jdt.internal.core.nd.field.StructDef;
import org.eclipse.jdt.internal.core.nd.util.CharArrayUtils;

public class JavaIndex {
	// Version constants
	static final int CURRENT_VERSION = Nd.version(1, 38);
	static final int MAX_SUPPORTED_VERSION = Nd.version(1, 38);
	static final int MIN_SUPPORTED_VERSION = Nd.version(1, 38);

	// Fields for the search header
	public static final FieldSearchIndex<NdResourceFile> FILES;
	public static final FieldSearchIndex<NdTypeId> SIMPLE_INDEX;
	public static final FieldSearchIndex<NdTypeId> TYPES;
	public static final FieldSearchIndex<NdMethodId> METHODS;

	public static final StructDef<JavaIndex> type;

	static {
		type = StructDef.create(JavaIndex.class);
		FILES = FieldSearchIndex.create(type, NdResourceFile.FILENAME);
		SIMPLE_INDEX = FieldSearchIndex.create(type, NdTypeId.SIMPLE_NAME);
		TYPES = FieldSearchIndex.create(type, NdTypeId.FIELD_DESCRIPTOR);
		METHODS = FieldSearchIndex.create(type, NdMethodId.METHOD_NAME);
		type.done();

		// This struct needs to fit within the first database chunk.
		assert type.getFactory().getRecordSize() <= Database.CHUNK_SIZE;
	}

	private final static class BestResourceFile implements FieldSearchIndex.IResultRank {
		public BestResourceFile() {
		}

		@Override
		public long getRank(Nd resourceFileNd, long resourceFileAddress) {
			return NdResourceFile.TIME_LAST_SCANNED.get(resourceFileNd, resourceFileAddress);
		}
	}

	private static final BestResourceFile bestResourceFile = new BestResourceFile();
	private final long address;
	private Nd nd;
	private IResultRank anyResult = new IResultRank() {
		@Override
		public long getRank(Nd dom, long address1) {
			return 1;
		}
	};
	private static Nd globalNd;
	private static final String INDEX_FILENAME = "index.db"; //$NON-NLS-1$
	private final static Object ndMutex = new Object();

	public JavaIndex(Nd dom, long address) {
		this.address = address;
		this.nd = dom;
	}

	/**
	 * Returns the most-recently-scanned resource file with the given name or null if none
	 */
	public NdResourceFile getResourceFile(char[] location) {
		return FILES.findBest(this.nd, this.address, FieldSearchIndex.SearchCriteria.create(location),
				bestResourceFile);
	}

	/**
	 * Returns true iff the given resource file is up-to-date with the filesystem. Returns false
	 * if the argument is out-of-date with the file system or null.
	 * 
	 * @param file the index file to look up or null
	 * @throws CoreException 
	 */
	public boolean isUpToDate(NdResourceFile file) throws CoreException {
		if (file != null && file.isDoneIndexing()) {
			// TODO(sxenos): It would be much more efficient to mark files as being in one
			// of three states: unknown, dirty, or clean. Files would start in the unknown
			// state and move into the dirty state when we see them in a java model change
			// event. They would move into the clean state after passing this sort of
			// fingerprint test... but by caching the state of all tested files (in memory),
			// it would eliminate the vast majority of these (slow) fingerprint tests.
			
			Path locationPath = new Path(file.getLocation().getString());
			if (file.getFingerprint().test(locationPath, null).matches()) {
				return true;
			}
		}
		return false;
	}

	public List<NdResourceFile> findResourcesWithPath(String thePath) {
		return FILES.findAll(this.nd, this.address, FieldSearchIndex.SearchCriteria.create(thePath.toCharArray()));
	}

	public List<NdResourceFile> getAllResourceFiles() {
		return FILES.asList(this.nd, this.address);
	}

	public NdTypeId findType(char[] fieldDescriptor) {
		SearchCriteria searchCriteria = SearchCriteria.create(fieldDescriptor);
		return TYPES.findBest(this.nd, this.address, searchCriteria, this.anyResult);
	}

	public boolean visitFieldDescriptorsStartingWith(char[] fieldDescriptorPrefix, FieldSearchIndex.Visitor<NdTypeId> visitor) {
		SearchCriteria searchCriteria = SearchCriteria.create(fieldDescriptorPrefix).prefix(true);
		return TYPES.visitAll(this.nd, this.address, searchCriteria, visitor);
	}

	/**
	 * Returns a type ID or creates a new one if it does not exist. The caller must
	 * attach a reference to it after calling this method or it may leak.
	 */
	public NdTypeId createTypeId(char[] fieldDescriptor) {
		NdTypeId existingType = findType(fieldDescriptor);

		if (existingType != null) {
			return existingType;
		}

		if (fieldDescriptor.length > 1) {
			if (fieldDescriptor[0] == 'L') {
				if (fieldDescriptor[fieldDescriptor.length - 1] != ';') {
					throw new IllegalStateException(new String(fieldDescriptor) + " is not a valid field descriptor"); //$NON-NLS-1$
				}
			}
		}

		NdTypeId result = new NdTypeId(this.nd, fieldDescriptor);
		if (!CharArrayUtils.equals(result.getFieldDescriptor().getChars(), fieldDescriptor)) {
			throw new IllegalStateException("Field descriptor didn't match"); //$NON-NLS-1$
		}
		return result;
	}

	public Nd getNd() {
		return this.nd;
	}

	public NdMethodId findMethodId(char[] methodId) {
		SearchCriteria searchCriteria = SearchCriteria.create(methodId);

		return METHODS.findBest(this.nd, this.address, searchCriteria, this.anyResult);
	}

	public NdMethodId createMethodId(char[] methodId) {
		NdMethodId existingMethod = findMethodId(methodId);

		if (existingMethod != null) {
			return existingMethod;
		}

		return new NdMethodId(this.nd, methodId);
	}

	/**
	 * Returns the absolute filesystem location of the given element or null if none
	 */
	public static IPath getLocationForElement(IJavaElement next) {
		IResource resource = next.getResource();

		if (resource != null) {
			return resource.getLocation() == null ? new Path("") : resource.getLocation(); //$NON-NLS-1$
		}

		return next.getPath();
	}

	public static boolean isEnabled() {
		IPreferencesService preferenceService = Platform.getPreferencesService();
		if (preferenceService == null) {
			return true;
		}
		return !preferenceService.getBoolean(JavaCore.PLUGIN_ID, "disableNewJavaIndex", false, //$NON-NLS-1$
				null);
	}

	public static Nd createNd(File databaseFile, ChunkCache chunkCache) {
		return new Nd(databaseFile, chunkCache, createTypeRegistry(),
				MIN_SUPPORTED_VERSION, MAX_SUPPORTED_VERSION, CURRENT_VERSION);
	}

	public static Nd getGlobalNd() {
		Nd localNd;
		synchronized (ndMutex) {
			localNd = globalNd;
		}

		if (localNd != null) {
			return localNd;
		}

		localNd = createNd(getDBFile(), ChunkCache.getSharedInstance());

		synchronized (ndMutex) {
			if (globalNd == null) {
				globalNd = localNd;
			}
			return globalNd;
		}
	}

	public static JavaIndex getIndex(Nd nd) {
		return new JavaIndex(nd, Database.DATA_AREA_OFFSET);
	}

	public static JavaIndex getIndex() {
		return getIndex(getGlobalNd());
	}

	public static int getCurrentVersion() {
		return CURRENT_VERSION;
	}

	static File getDBFile() {
		IPath stateLocation = JavaCore.getPlugin().getStateLocation();
		return stateLocation.append(INDEX_FILENAME).toFile();
	}

	static NdNodeTypeRegistry<NdNode> createTypeRegistry() {
		NdNodeTypeRegistry<NdNode> registry = new NdNodeTypeRegistry<>();
		registry.register(0x0001, NdAnnotation.type.getFactory());
		registry.register(0x0004, NdAnnotationInConstant.type.getFactory());
		registry.register(0x0008, NdAnnotationInMethod.type.getFactory());
		registry.register(0x000c, NdAnnotationInMethodParameter.type.getFactory());
		registry.register(0x0010, NdAnnotationInType.type.getFactory());
		registry.register(0x0014, NdAnnotationInVariable.type.getFactory());
		registry.register(0x0020, NdAnnotationValuePair.type.getFactory());
		registry.register(0x0028, NdBinding.type.getFactory());
		registry.register(0x0030, NdComplexTypeSignature.type.getFactory());
		registry.register(0x0038, NdConstant.type.getFactory());
		registry.register(0x0040, NdConstantAnnotation.type.getFactory());
		registry.register(0x0050, NdConstantArray.type.getFactory());
		registry.register(0x0060, NdConstantBoolean.type.getFactory());
		registry.register(0x0070, NdConstantByte.type.getFactory());
		registry.register(0x0080, NdConstantChar.type.getFactory());
		registry.register(0x0090, NdConstantClass.type.getFactory());
		registry.register(0x00A0, NdConstantDouble.type.getFactory());
		registry.register(0x00B0, NdConstantEnum.type.getFactory());
		registry.register(0x00C0, NdConstantFloat.type.getFactory());
		registry.register(0x00D0, NdConstantInt.type.getFactory());
		registry.register(0x00E0, NdConstantLong.type.getFactory());
		registry.register(0x00F0, NdConstantShort.type.getFactory());
		registry.register(0x0100, NdConstantString.type.getFactory());
		registry.register(0x0110, NdMethod.type.getFactory());
		registry.register(0x0120, NdMethodException.type.getFactory());
		registry.register(0x0130, NdMethodId.type.getFactory());
		registry.register(0x0140, NdMethodParameter.type.getFactory());
		registry.register(0x0150, NdResourceFile.type.getFactory());
		registry.register(0x0160, NdTreeNode.type.getFactory());
		registry.register(0x0170, NdType.type.getFactory());
		registry.register(0x0180, NdTypeAnnotation.type.getFactory());
		registry.register(0x0184, NdTypeAnnotationInMethod.type.getFactory());
		registry.register(0x0188, NdTypeAnnotationInType.type.getFactory());
		registry.register(0x018c, NdTypeAnnotationInVariable.type.getFactory());
		registry.register(0x0190, NdTypeArgument.type.getFactory());
		registry.register(0x0194, NdTypeBound.type.getFactory());
		registry.register(0x01A0, NdTypeInterface.type.getFactory());
		registry.register(0x01B0, NdTypeParameter.type.getFactory());
		registry.register(0x01C0, NdTypeSignature.type.getFactory());
		registry.register(0x01D0, NdTypeId.type.getFactory());
		registry.register(0x01E0, NdTypeInterface.type.getFactory());
		registry.register(0x01F0, NdVariable.type.getFactory());
		registry.register(0x0200, NdWorkspaceLocation.type.getFactory());
		return registry;
	}
}
