/*******************************************************************************
 * Copyright (c) 2010, 2011 Nokia 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:
 * Nokia - Initial API and implementation
 * Broadcom - loadSectionIntoHeap() buffer creation optimization
 *******************************************************************************/
package org.eclipse.cdt.debug.edc.internal.symbols.files;

import java.io.IOException;
import java.nio.ByteOrder;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.cdt.debug.edc.IStreamBuffer;
import org.eclipse.cdt.debug.edc.internal.EDCDebugger;
import org.eclipse.cdt.debug.edc.internal.FileStreamBuffer;
import org.eclipse.cdt.debug.edc.internal.MemoryStreamBuffer;
import org.eclipse.cdt.utils.ERandomAccessFile;
import org.eclipse.core.runtime.IPath;

/**
 * Handle mapping sections into memory and caching this content.
 */
public class SectionMapper implements ISectionMapper {
	
	private final IPath hostFile;
	private final boolean isLE;
	private ERandomAccessFile efile;
	/** all sections loaded for any reason */
	private Map<SectionInfo, IStreamBuffer> loadedSections;	
	/** subset of sections loaded into memory maps */
	private Map<SectionInfo, IStreamBuffer> mappedBuffers;
	
	public SectionMapper(IPath hostFile, boolean isLE) {
		this.hostFile = hostFile;
		this.isLE = isLE;
		this.efile = null;
		this.loadedSections = new HashMap<SectionInfo, IStreamBuffer>();
		this.mappedBuffers = new HashMap<SectionInfo, IStreamBuffer>();
	}
	
	public void dispose() {
		for (Map.Entry<SectionInfo, IStreamBuffer> entry: loadedSections.entrySet()) {
			IStreamBuffer buffer = entry.getValue();
			if (buffer == null)
				continue;
			if (mappedBuffers.containsKey(entry.getKey()))
				FileStatistics.currentMemoryMappedBuffers -= buffer.capacity();
			else
				FileStatistics.currentHeapAllocatedBuffers -= buffer.capacity();
		}
		loadedSections.clear();
		mappedBuffers.clear();
		close();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.ISectionMapper#getMappedFile()
	 */
	public IPath getMappedFile() {
		return hostFile;
	}
	
	/**
	 * 
	 */
	private void ensureOpen() throws IOException {
		if (efile == null) {
			FileStatistics.log("Opening " + hostFile.toFile());
			FileStatistics.executablesOpened++;
			FileStatistics.executablesOpen++;
			efile = new ERandomAccessFile(hostFile.toFile(), "r");
		}
	}


	private void close() {
		if (!mappedBuffers.isEmpty())
			throw new IllegalStateException("cannot close file; mapped buffers open");
		if (efile != null) {
			try {
				FileStatistics.log("Closing " + hostFile.toFile());
				FileStatistics.executablesOpen--;
				efile.close();
			} catch (IOException e) {
				// ignore
			}
		}
		efile = null;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.IExecutableSectionMapper#getSectionBuffer(org.eclipse.cdt.debug.edc.internal.symbols.exe.SectionInfo)
	 */
	public IStreamBuffer getSectionBuffer(SectionInfo section) throws IOException {
		
		ensureOpen();

		IStreamBuffer buffer = loadedSections.get(section);
		if (buffer == null) {
			buffer = loadSection(section);
			
			loadedSections.put(section, buffer);
			// TODO: flush data occasionally, before #dispose()
		}
		
		return buffer;
	}

	private IStreamBuffer loadSection(SectionInfo section)
			throws IOException {
		FileStatistics.log("Loading " + section + " from " + hostFile.toFile());
		
		IStreamBuffer buffer = null;
		
		// If the sym file is too large, it's useless reading it 
		// into the heap and choking the memory.
		// Just read it on-demand from disk.
		try {
			if (section.sectionSize > 4 * 1024 * 1024) {
				buffer = loadSectionIntoFileStreamBuffer(section);
			} else {
				buffer = loadSectionIntoHeap(section);
			}
		} catch (IOException e) {
			buffer = loadSectionIntoHeap(section);
		}
		
		return buffer;
	}

	/**
	 * Load section contents into a streaming buffer.  This is a little slower but 
	 * does not allocate any more than a page of memory at a time.
	 * 
	 * @param section
	 * @param buffer
	 * @return new {@link IStreamBuffer}
	 */
	private IStreamBuffer loadSectionIntoFileStreamBuffer(SectionInfo section) throws IOException {
		IStreamBuffer buffer = null;
		try {
			buffer = new FileStreamBuffer(efile, isLE ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN, 
					section.fileOffset, section.sectionSize);
			mappedBuffers.put(section, buffer);
			FileStatistics.currentMemoryMappedBuffers += buffer.capacity();
			FileStatistics.totalMemoryMappedBuffers += buffer.capacity();
		} catch (Throwable e2) {
			EDCDebugger.getMessageLogger().logError("Failed to make buffer for section " + section, e2);
		}
		return buffer;
	}

	private IStreamBuffer loadSectionIntoHeap(SectionInfo section)
			throws IOException {
		IStreamBuffer buffer;
		// try to load the section into memory because it will
		// be faster
		byte[] data = new byte[(int)section.sectionSize];
		efile.seek(section.fileOffset);
		int bytesRead = efile.read(data);
		buffer = new MemoryStreamBuffer(data, isLE ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN,
										0 , (bytesRead != -1) ? bytesRead : 0);
		FileStatistics.currentHeapAllocatedBuffers += data.length;
		FileStatistics.totalHeapAllocatedBuffers += data.length;
		return buffer;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.cdt.debug.edc.internal.symbols.exe.ISectionMapper#releaseBuffer(java.nio.ByteBuffer)
	 */
	public void releaseSectionBuffer(SectionInfo section) {
		IStreamBuffer buffer = loadedSections.remove(section);
		if (buffer != null) {
			if (mappedBuffers.remove(section) != null) {
				FileStatistics.currentMemoryMappedBuffers -= buffer.capacity();
				if (mappedBuffers.isEmpty()) {
					close();
				}
			} else {
				FileStatistics.currentHeapAllocatedBuffers -= buffer.capacity();
			}
		}
	}
	
}
