/*******************************************************************************
 * Copyright (c) 2000, 2003 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Common Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/cpl-v10.html
 * 
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.cdt.internal.core.index.impl;

import java.io.File;
import java.io.IOException;

import org.eclipse.cdt.internal.core.index.IDocument;

/**
 * This index stores the document names in an <code>ObjectVector</code>, and the words in
 * an <code>HashtableOfObjects</code>.
 */

public class InMemoryIndex {

	/**
	* hashtable of IncludeEntrys = includeFiles+numbers of the files they appear in.
	*/
	protected IncludeEntryHashedArray includes;
	/**
	 * hashtable of WordEntrys = words+numbers of the files they appear in.
	 */
	protected WordEntryHashedArray words;
	/**
	 * List of IndexedFiles = file name + a unique number.
	 */
	protected IndexedFileHashedArray files;
	/**
	 * Size of the index.
	 */
	protected long footprint;

	private IncludeEntry[] sortedIncludeEntries;
	private WordEntry[] sortedWordEntries;
	private IndexedFile[] sortedFiles;

	private int lastId;
	
	public InMemoryIndex() {
		includes= new IncludeEntryHashedArray(501);
		init();
	}

	public IndexedFile addDocument(IDocument document) {
		IndexedFile indexedFile= this.files.add(document);
		this.footprint += indexedFile.footprint() + 4;
		this.sortedFiles = null;
		return indexedFile;
	}
	
	public void addIncludeRef(IndexedFile indexedFile, char[] include) {
		addIncludeRef(include, indexedFile.getFileNumber());
	}
	
	public void addIncludeRef(IndexedFile indexedFile, String include) {
		addIncludeRef(include.toCharArray(), indexedFile.getFileNumber());
	}
	
	/**
		 * Adds the references of the include to the tree (reference = number of the file the include belongs to).
		 */
		protected void addIncludeRef(char[] include, int[] references) {
			int size= references.length;
			int i= 0;
			while (i < size) {
				if (references[i] != 0)
					addIncludeRef(include, references[i]);
				i++;
			}
		}
		/**
		 * Looks if the include already exists to the tree and adds the fileNum to this include.
		 * If the include does not exist, it adds it to the tree.
		 */
		protected void addIncludeRef(char[] include, int fileNum) {
			IncludeEntry entry= (IncludeEntry) this.includes.get(include);
			if (entry == null) {
				entry= new IncludeEntry(include, ++lastId);
				entry.addRef(fileNum);
				this.includes.add(entry);
				this.sortedIncludeEntries= null;
				//TODO: BOG FIGURE OUT FOOTPRINT
				//this.footprint += entry.getClass(); //footprint();
				//
			} else {
				this.footprint += entry.addRef(fileNum);
			}
		}

	/**
	 * Adds the references of the word to the index (reference = number of the file the word belongs to).
	 */
	protected void addRef(char[] word, int[] references) {
		int size= references.length;
		int i= 0;
		while (i < size) {
			if (references[i] != 0)
				addRef(word, references[i]);
			i++;
		}
	}
	/**
	 * Looks if the word already exists in the index and add the fileNum to this word.
	 * If the word does not exist, it adds it in the index.
	 */
	protected void addRef(char[] word, int fileNum) {
		WordEntry entry= (WordEntry) this.words.get(word);
		if (entry == null) {
			entry= new WordEntry(word);
			entry.addRef(fileNum);
			this.words.add(entry);
			this.sortedWordEntries= null;
			this.footprint += entry.footprint();
		} else {
			this.footprint += entry.addRef(fileNum);
		}
	}

	public void addRef(IndexedFile indexedFile, char[] word) {
		addRef(word, indexedFile.getFileNumber());
	}

	public void addRef(IndexedFile indexedFile, String word) {
		addRef(word.toCharArray(), indexedFile.getFileNumber());
	}
	
	public void addRelatives(IndexedFile indexedFile, String inclusion, String parent) {
		addRelatives(indexedFile.getFileNumber(),inclusion.toCharArray(),(parent != null ) ? parent.toCharArray() : null);
	}
	
	protected void addRelatives(int fileNumber, char[] inclusion, char[] parent) {
		IncludeEntry childEntry=null;
		IncludeEntry parentEntry=null;
		
		if (inclusion != null)
			childEntry= (IncludeEntry) this.includes.get(inclusion);
	
		if (parent != null)
			parentEntry= (IncludeEntry) this.includes.get(parent);
		

		childEntry.addParent(fileNumber,(parentEntry!=null) ? parentEntry.getID() : -1);
		
		if (parent!=null)
			parentEntry.addChild(fileNumber,(childEntry!=null) ? childEntry.getID() : -1);
	}	
	/**
	 * Returns the footprint of the index.
	 */
	public long getFootprint() {
		return this.footprint;
	}
	/**
	 * Returns the indexed files contained in the hashtable of includes.
	 */
	public IndexedFile[] getIndexedFiles(){
		return this.files.asArray();
	}
	/**
	 * Returns the indexed file with the given path, or null if such file does not exist.
	 */
	public IndexedFile getIndexedFile(String path) {
		return files.get(path);
	}
	/**
	 * Returns the include entries contained in the hashtable of includes.
	 */
	public IncludeEntry[] getIncludeEntries() {
		return this.includes.asArray();
	}
	/**
	 * Returns the include entry corresponding to the given include.
	 */
	protected IncludeEntry getIncludeEntry(char[] include) {
		return (IncludeEntry) includes.get(include);
	}
	/**
	 * @see IIndex#getNumDocuments()
	 */
	public int getNumFiles() {
		return files.size();
	}
	/**
	 * @see IIndex#getNumWords()
	 */
	public int getNumWords() {
		return words.elementSize;
	}
	
	public int getNumIncludes() {
		return includes.elementSize;
	}
	
	/**
	 * Returns the words contained in the hashtable of words, sorted by alphabetical order.
	 */
	protected IndexedFile[] getSortedFiles() {
		if (this.sortedFiles == null) {
			IndexedFile[] indexedFiles= files.asArray();
			Util.sort(indexedFiles);
			this.sortedFiles= indexedFiles;
		}
		return this.sortedFiles;
	}
	/**
	 * Returns the word entries contained in the hashtable of words, sorted by alphabetical order.
	 */
	protected WordEntry[] getSortedWordEntries() {
		if (this.sortedWordEntries == null) {
			WordEntry[] words= this.words.asArray();
			Util.sort(words);
			this.sortedWordEntries= words;
		}
		return this.sortedWordEntries;
	}
	/**
	 * Returns the include entries contained in the hashtable of includeas, sorted by alphabetical order.
	 */
	protected IncludeEntry[] getSortedIncludeEntries() {
		if (this.sortedIncludeEntries == null) {
			IncludeEntry[] includes= this.includes.asArray();
			Util.sort(includes);
			this.sortedIncludeEntries= includes;
		}
		return this.sortedIncludeEntries;
	}
	/**
	 * Returns the word entry corresponding to the given word.
	 */
	protected WordEntry getWordEntry(char[] word) {
		return (WordEntry) words.get(word);
	}
	/**
	 * Initialises the fields of the index
	 */
	public void init() {
		includes= new IncludeEntryHashedArray(501);
		words= new WordEntryHashedArray(501);
		files= new IndexedFileHashedArray(101);
		footprint= 0;
		lastId=0;
		sortedWordEntries= null;
		sortedFiles= null;
		sortedIncludeEntries=null;
	}
	/**
	 * Saves the index in the given file.
	 * Structure of the saved Index :
	 *   - IndexedFiles in sorted order.
	 *		+ example: 
	 *			"c:/com/a.cpp 1"
	 *			"c:/com/b.cpp 2"
	 *   - References with the words in sorted order
	 *		+ example: 
	 *			"classDecl/a 1"
	 *			"classDecl/b 2"
	 *			"ref/String 1 2"
	 */
	public void save(File file) throws IOException {
		BlocksIndexOutput output= new BlocksIndexOutput(file);
		save(output);
	}
	/**
	 * Saves the index in the given IndexOutput.
	 * Structure of the saved Index :
	 *   - IndexedFiles in sorted order.
	 *		+ example: 
	 *			"c:/com/a.cpp 1"
	 *			"c:/com/b.cpp 2"
	 *   - References with the words in sorted order
	 *		+ example: 
	 *			"classDecl/a 1"
	 *			"classDecl/b 2"
	 *			"ref/String 1 2"
	 */
	protected void save(IndexOutput output) throws IOException {
		boolean ok= false;
		try {
			output.open();
			IndexedFile[] indexedFiles= files.asArray();
			for (int i= 0, length = indexedFiles.length; i < length; ++i)
				output.addFile(indexedFiles[i]); // written out in order BUT not alphabetical
			getSortedWordEntries(); // init the slot
			for (int i= 0, numWords= sortedWordEntries.length; i < numWords; ++i)
				output.addWord(sortedWordEntries[i]);
			output.flush();
			output.close();
			ok= true;
		} finally {
			if (!ok && output != null)
				output.close();
		}
	}
}

