/*******************************************************************************
 * 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.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;

import org.eclipse.cdt.internal.core.CharOperation;

/**
 * An indexSummary is used when saving an index into a BlocksIndexOuput or 
 * reading it from a BlocksIndexInput. It contains basic informations about 
 * an index: first files/words in each block, number of files/words.
 */

public class IndexSummary {
	/**
	 * First file for each block.
	 */
	protected ArrayList firstFilesInBlocks= new ArrayList();
	/**
	 * First word for each block.
	 */
	protected ArrayList firstWordsInBlocks= new ArrayList();
	/**
	 * First include for each block.
	 */
	protected ArrayList firstIncludesInBlocks= new ArrayList();
	/**
	 * Number of files in the index.
	 */
	protected int numFiles;
	/**
	 * Number of words in the index.
	 */
	protected int numWords;
	/**
	 * Number of includes in the index.
	 */
	protected int numIncludes;
	
	static class FirstFileInBlock {
		IndexedFile indexedFile;
		int blockNum;
	}

	static class FirstWordInBlock {
		char[] word;
		int blockNum;
		public String toString(){
			return "FirstWordInBlock: " + new String(word) + ", blockNum: " + blockNum; //$NON-NLS-1$ //$NON-NLS-2$
		}
	}

	static class FirstIncludeInBlock {
		char[] file;
		int blockNum;
		public String toString(){
			return "FirstIncludeInBlock: " + new String(file) + ", blockNum: " + blockNum; //$NON-NLS-1$ //$NON-NLS-2$
		}
	}
	
	protected int firstWordBlockNum;
	protected boolean firstWordAdded= true;
	
	protected int firstIncludeBlockNum;
	protected boolean firstIncludeBlockAdded= true;
	/**
	 * Adds the given file as the first file for the given Block number. 
	 */
	public void addFirstFileInBlock(IndexedFile indexedFile, int blockNum) {
		FirstFileInBlock entry= new FirstFileInBlock();
		entry.indexedFile= indexedFile;
		entry.blockNum= blockNum;
		firstFilesInBlocks.add(entry);
	}
	/**
	 * Adds the given word as the first word for the given Block number. 
	 */
	public void addFirstWordInBlock(char[] word, int blockNum) {
		if (firstWordAdded) {
			firstWordBlockNum= blockNum;
			firstWordAdded= false;
		}
		FirstWordInBlock entry= new FirstWordInBlock();
		entry.word= word;
		entry.blockNum= blockNum;
		firstWordsInBlocks.add(entry);
	}
	/**
	 * Adds the given include as the first include for the given Block number. 
	 */
	public void addFirstIncludeInBlock(char[] file, int blockNum) {
		if (firstIncludeBlockAdded) {
			firstIncludeBlockNum= blockNum;
			firstIncludeBlockAdded= false;
		}
		FirstIncludeInBlock entry= new FirstIncludeInBlock();
		entry.file = file;
		entry.blockNum= blockNum;
		firstIncludesInBlocks.add(entry);
	}
	/**
	 * Returns the numbers of all the blocks
	 */
	public int[] getAllBlockNums() {

		int max = firstWordsInBlocks.size();
		int[] blockNums = new int[max];
		for (int i = 0; i < max; i++){
			blockNums[i] = ((FirstWordInBlock)firstWordsInBlocks.get(i)).blockNum;
		}
		return blockNums;
	}
	public int getBlockNum(int blockLocation) {
	return ((FirstWordInBlock) firstWordsInBlocks.get(blockLocation)).blockNum;
	}
	/**
	 * Returns the number of the Block containing the file with the given number. 
	 */
	public int getBlockNumForFileNum(int fileNum) {
		int min= 0;
		int max= firstFilesInBlocks.size() - 1;
		while (min <= max) {
			int mid= (min + max) / 2;
			FirstFileInBlock entry= (FirstFileInBlock) firstFilesInBlocks.get(mid);
			int compare= fileNum - entry.indexedFile.getFileNumber();
			if (compare == 0)
				return entry.blockNum;
			if (compare < 0)
				max= mid - 1;
			else
				min= mid + 1;
		}
		if (max < 0)
			return -1;
		FirstFileInBlock entry= (FirstFileInBlock) firstFilesInBlocks.get(max);
		return entry.blockNum;
	}
	/**
	 * Returns the number of the Block containing the given word. 
	 */
	public int getBlockNumForWord(char[] word) {
		int min= 0;
		int max= firstWordsInBlocks.size() - 1;
		while (min <= max) {
			int mid= (min + max) / 2;
			FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(mid);
			int compare= Util.compare(word, entry.word);
			if (compare == 0)
				return entry.blockNum;
			if (compare < 0)
				max= mid - 1;
			else
				min= mid + 1;
		}
		if (max < 0)
			return -1;
		FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(max);
		return entry.blockNum;
	}
	public int[] getBlockNumsForPrefix(char[] prefix) {
		int min= 0;
		int size= firstWordsInBlocks.size();
		int max=  size - 1;
		int match= -1;
		while (min <= max && match < 0) {
			int mid= (min + max) / 2;
			FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(mid);
			int compare= CharOperation.compareWith(entry.word, prefix);
			if (compare == 0) {
				match= mid;
				break;
			}	
			if (compare >= 0)
				max= mid - 1;
			else
				min= mid + 1;
		}
		if (max < 0)
			return new int[0];
			
		if (match < 0)
			match= max;
		
		int firstBlock= match - 1;
		// Look if previous blocks are affected
		for (; firstBlock >= 0; firstBlock--) {
			FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(firstBlock);
			if (!CharOperation.prefixEquals(prefix, entry.word))
				break;
		}
		if (firstBlock < 0)
			firstBlock= 0;	
		
		// Look if next blocks are affected
		int firstNotIncludedBlock= match + 1;
		for (; firstNotIncludedBlock < size; firstNotIncludedBlock++) {
			FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(firstNotIncludedBlock);
			if (!CharOperation.prefixEquals(prefix, entry.word))
				break;
		}
		
		int numberOfBlocks= firstNotIncludedBlock - firstBlock;
		int[] result= new int[numberOfBlocks];
		int pos= firstBlock;
		for (int i= 0; i < numberOfBlocks; i++, pos++) {
			FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(pos);
			result[i]= entry.blockNum;
		}
		return result;
	}
	public int[] getBlockNumsForIncludes() {
		int max = firstIncludesInBlocks.size();
		int[] blockNums = new int[max];
		for (int i = 0; i < max; i++){
			blockNums[i] = ((FirstIncludeInBlock)firstIncludesInBlocks.get(i)).blockNum;
		}
		return blockNums;
	}
	public int getFirstBlockLocationForPrefix(char[] prefix) {
		int min = 0;
		int size = firstWordsInBlocks.size();
		int max = size - 1;
		int match = -1;
		while (min <= max) {
			int mid = (min + max) / 2;
			FirstWordInBlock entry = (FirstWordInBlock) firstWordsInBlocks.get(mid);
			int compare = CharOperation.compareWith(entry.word, prefix);
			if (compare == 0) {
				match = mid;
				break;
			}
			if (compare >= 0) {
				max = mid - 1;
			} else {
				match = mid; // not perfect match, but could be inside
				min = mid + 1;
			}
		}
		if (max < 0) return -1;
	
		// no match at all, might be some matching entries inside max block
		if (match < 0){
			match = max;
		} else {
			// look for possible matches inside previous blocks
			while (match > 0){
				FirstWordInBlock entry = (FirstWordInBlock) firstWordsInBlocks.get(match);
				if (!CharOperation.prefixEquals(prefix, entry.word))
					break;
				match--;
			}
		}
		return match;
	}
	/**
	 * Returns the number of the first IndexBlock (containing words).
	 */
	public int getFirstWordBlockNum() {
		return firstWordBlockNum;
	}
	/**
	 * Returns the number of the first IndexBlock (containing words).
	 */
	public int getFirstIncludeBlockNum() {
		return firstIncludeBlockNum;
	}
	/** 
	 * Blocks are contiguous, so the next one is a potential candidate if its first word starts with
	 * the given prefix
	 */
	public int getNextBlockLocationForPrefix(char[] prefix, int blockLoc) {
		if (++blockLoc < firstWordsInBlocks.size()){
			FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(blockLoc);
			if (CharOperation.prefixEquals(prefix, entry.word)) return blockLoc;
		}
		return -1;
	}
	/**
	 * Returns the number of files contained in the index.
	 */
	public int getNumFiles() {
		return numFiles;
	}
	/**
	 * Returns the number of words contained in the index.
	 */
	public int getNumWords() {
		return numWords;
	}
	/**
	 * Returns the number of words contained in the index.
	 */
	public int getNumIncludes() {
		return numIncludes;
	}
	/**
	 * Loads the summary in memory.
	 */
	public void read(RandomAccessFile raf) throws IOException {
		numFiles= raf.readInt();
		numWords= raf.readInt();
		numIncludes= raf.readInt();
		firstWordBlockNum= raf.readInt();
		firstIncludeBlockNum= raf.readInt();
		int numFirstFiles= raf.readInt();
		for (int i= 0; i < numFirstFiles; ++i) {
			FirstFileInBlock entry= new FirstFileInBlock();
			String path= raf.readUTF();
			int fileNum= raf.readInt();
			entry.indexedFile= new IndexedFile(path, fileNum);
			entry.blockNum= raf.readInt();
			firstFilesInBlocks.add(entry);
		}
		int numFirstWords= raf.readInt();
		for (int i= 0; i < numFirstWords; ++i) {
			FirstWordInBlock entry= new FirstWordInBlock();
			entry.word= raf.readUTF().toCharArray();
			entry.blockNum= raf.readInt();
			firstWordsInBlocks.add(entry);
		}
		int numIncludes = raf.readInt();
		for (int i= 0; i < numIncludes; ++i) {
			FirstIncludeInBlock entry= new FirstIncludeInBlock();
			entry.file= raf.readUTF().toCharArray();
			entry.blockNum= raf.readInt();
			firstIncludesInBlocks.add(entry);
		}
	}
	/**
	 * Sets the number of files of the index.
	 */

	public void setNumFiles(int numFiles) {
		this.numFiles= numFiles;
	}
	/**
	 * Sets the number of words of the index.
	 */

	public void setNumWords(int numWords) {
		this.numWords= numWords;
	}
	/**
	 * Sets the number of includes of the index.
	 */
	public void setNumIncludes(int numIncs) {
		this.numIncludes= numIncs;
	}
	/**
	 * Saves the summary on the disk.
	 */
	public void write(RandomAccessFile raf) throws IOException {
		raf.writeInt(numFiles);
		raf.writeInt(numWords);
		raf.writeInt(numIncludes);
		raf.writeInt(firstWordBlockNum);
		raf.writeInt(firstIncludeBlockNum);
		raf.writeInt(firstFilesInBlocks.size());
		for (int i= 0, size= firstFilesInBlocks.size(); i < size; ++i) {
			FirstFileInBlock entry= (FirstFileInBlock) firstFilesInBlocks.get(i);
			raf.writeUTF(entry.indexedFile.getPath());
			raf.writeInt(entry.indexedFile.getFileNumber());
			raf.writeInt(entry.blockNum);
		}
		raf.writeInt(firstWordsInBlocks.size());
		for (int i= 0, size= firstWordsInBlocks.size(); i < size; ++i) {
			FirstWordInBlock entry= (FirstWordInBlock) firstWordsInBlocks.get(i);
			raf.writeUTF(new String(entry.word));
			raf.writeInt(entry.blockNum);
		}
		raf.writeInt(firstIncludesInBlocks.size());
		for (int i= 0, size= firstIncludesInBlocks.size(); i < size; ++i) {
			FirstIncludeInBlock entry= (FirstIncludeInBlock) firstIncludesInBlocks.get(i);
			raf.writeUTF(new String(entry.file));
			raf.writeInt(entry.blockNum);
		}
	}
}

