/*******************************************************************************
 * Copyright (c) 2009, 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 - remove duplicate child methods (repeating super methods from Scope)
 *******************************************************************************/
package org.eclipse.cdt.debug.edc.internal.symbols.dwarf;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.cdt.core.IAddress;
import org.eclipse.cdt.debug.edc.internal.symbols.CompileUnitScope;
import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.AttributeList;
import org.eclipse.cdt.debug.edc.internal.symbols.dwarf.DwarfDebugInfoProvider.CompilationUnitHeader;
import org.eclipse.cdt.debug.edc.symbols.IFunctionScope;
import org.eclipse.cdt.debug.edc.symbols.ILineEntry;
import org.eclipse.cdt.debug.edc.symbols.IModuleScope;
import org.eclipse.cdt.debug.edc.symbols.IScope;
import org.eclipse.cdt.debug.edc.symbols.IVariable;
import org.eclipse.core.runtime.IPath;

/**
 * extension of CompileUnitScope that holds<br>
 * 1) DWARF specific debug info provider<br>
 * 2) DWARF specific attributes<br>
 * 3) DWARF sepcific compile unit header<br>
 * 4) cache flags for previously parsed variables, addresses & types
 *
 */
public class DwarfCompileUnit extends CompileUnitScope {

	protected DwarfDebugInfoProvider provider;
	protected AttributeList attributes;
	private List<IPath> fileList;
	private boolean rangesDirty;

	/** computation unit header */
	protected final CompilationUnitHeader header;
	
	/** whether the computation unit has been parsed to find variables and children with address ranges */
	protected boolean parsedForVarsAndAddresses = false;
	
	/** whether the computation unit has been parsed to find types */
	protected boolean parsedForTypes = false;

	
	/**
	 * DwarfCompileUnit holds the provider, attributes and DWARF header
	 * in addition to other member variables of its super, 
	 * {@link CompileUnitScope#CompileUnitScope(IPath, IModuleScope, IAddress, IAddress)}
	 * @param provider
	 * @param parent
	 * @param filePath
	 * @param lowAddress
	 * @param highAddress
	 * @param header
	 * @param hasChildren
	 * @param attributes
	 */
	public DwarfCompileUnit(DwarfDebugInfoProvider provider, IModuleScope parent, IPath filePath,
			IAddress lowAddress, IAddress highAddress, CompilationUnitHeader header, boolean hasChildren,
			AttributeList attributes) {
		super(filePath, parent, lowAddress, highAddress);

		this.provider = provider;
		this.attributes = attributes;
		this.header = header;
		
		// if there are no children, say the children have been parsed
		if (!hasChildren) {
			this.parsedForVarsAndAddresses = true;
			this.parsedForTypes = true;
		}
	}

	/**
	 * called by {@link CompileUnitScope#hashCode()}.
	 * this implementation further distinguishes the hash-code
	 * by adding the following to the caller hashCode as follows:
	 * <br><code>
	 * (prime+header.debugInfoOffset)*prime+provider.symbolfFile.hashCode()
	 * </code>
	 * @see CompileUnitScope#cuScopeHashCode()
	 */
	protected int cuScopeHashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + header.debugInfoOffset;
		result = prime * result + provider.getSymbolFile().hashCode();
		return result;
	}

	/**
	 * called by {@link CompileUnitScope#equals(Object)}.
	 * caller will guarantee objects are not identical, non-null,
	 * of same class, with the same scope name.
	 * This implementation further guarantees equality:
	 * <br>(1) if and only if debugInfoOffset values are equal
	 * <br>(2) if and only if provider symbol file values are equal
	 * @see CompileUnitScope#cuScopeEquals(java.lang.Object)
	 */
	protected boolean cuScopeEquals(Object obj) {
		DwarfCompileUnit other = (DwarfCompileUnit) obj;
		if (header.debugInfoOffset != other.header.debugInfoOffset)
			return false;
		if (!provider.getSymbolFile().equals(other.provider.getSymbolFile()))
			return false;
		return true;
	}

	/**
	 * @return attributes of this DwarfCompileUnit
	 */
	public AttributeList getAttributeList() {
		return attributes;
	}
	
	/**
	 * utilize DwarfInfoReader to implement abstract declaration in
	 * {@link CompileUnitScope#parseLineTable()}
	 */
	protected Collection<ILineEntry> parseLineTable() {
		DwarfInfoReader reader = new DwarfInfoReader(provider);
		fileList = new ArrayList<IPath>();
		return reader.parseLineTable(this, attributes, fileList);
	}
	
	/** fixup ranges and ensure parsed for addresses before calling
	 * super.getFunctionAtAddress()
	 * @see org.eclipse.cdt.debug.edc.internal.symbols.CompileUnitScope#getFunctionAtAddress(org.eclipse.cdt.core.IAddress)
	 */
	@Override
	public IFunctionScope getFunctionAtAddress(IAddress linkAddress) {
		if (rangesDirty) {
			fixupRanges();
		}
		ensureParsedForAddresses();
		return super.getFunctionAtAddress(linkAddress);
	}
	
	/** ensure parsed for addresses before calling super.getFunctions
	 * @see org.eclipse.cdt.debug.edc.internal.symbols.CompileUnitScope#getFunctions()
	 */
	@Override
	public Collection<IFunctionScope> getFunctions() {
		ensureParsedForAddresses();
		return super.getFunctions();
	}
	
	/**
	 * For compilers that don't generate compile unit scopes, e.g. GCCE with
	 * dlls, this fixes up the low and high addresses of the compile unit based
	 * on the function scopes
	 */
	protected void fixupRanges() {
		
		// fix up scope addresses in case compiler doesn't generate them.
		if (hasEmptyRange() && parsedForVarsAndAddresses) {
			fixupRanges(provider.getBaseLinkAddress());
		}

		rangesDirty = false;
	}
	
// Don't override this here. It causes unnecessary parsing 
// wasting memory & time.
//	@Override
//	public Collection<IScope> getChildren() {
//		ensureParsedForAddresses();
//		return super.getChildren();
//	}

	/**
	 * allow the caller to establish an attribute list
	 */
	public void setAttributes(AttributeList attributes) {
		this.attributes = attributes;
	}

	/**
	 * @return whether or not this DwarfCompileUnit has been parsed for addresses
	 */
	public boolean isParsedForAddresses() {
		return parsedForVarsAndAddresses;
	}

	/**
	 * @return whether or not this DwarfCompileUnit has been parsed for variables
	 */
	public boolean isParsedForVariables() {
		return parsedForVarsAndAddresses;
	}

	/**
	 * @return whether or not this DwarfCompileUnit has been parsed for types
	 */
	public boolean isParsedForTypes() {
		return parsedForTypes;
	}

	/** ensure first parsed for variables before calling
	 * {@link CompileUnitScope#getVariables()}
	 * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getVariables()
	 */
	@Override
	public Collection<IVariable> getVariables() {
		ensureParsedForVariables();
		return super.getVariables();
	}

	/**
	 * allow caller to set this DwarfCompileUnit's parsedForVarsAndAddresses flag true
	 * @param parsedForAddresses
	 */
	public void setParsedForAddresses(boolean parsedForAddresses) {
		this.parsedForVarsAndAddresses = parsedForAddresses;
	}

	/**
	 * allow caller to set this DwarfCompileUnit's parsedForVarsAndAddresses flag true
	 * @param parsedForVariables
	 */
	public void setParsedForVariables(boolean parsedForVariables) {
		this.parsedForVarsAndAddresses = parsedForVariables;
	}

	/**
	 * allow caller to set this DwarfCompileUnit's parsedForTypes flag true
	 * @param parsedForTypes
	 */
	public void setParsedForTypes(boolean parsedForTypes) {
		this.parsedForTypes = parsedForTypes;
	}

	private void ensureParsedForAddresses() {
		if (!parsedForVarsAndAddresses) {
			DwarfInfoReader reader = new DwarfInfoReader(provider);
			reader.parseCompilationUnitForAddresses(this);
			fixupRanges();
		}
	}
	
	/**
	 * Get the file path for a file number
	 * @param declFileNum
	 * @return IPath for the file, or <code>null</code>
	 */
	public IPath getFileEntry(int declFileNum) {
		if (fileList == null)
			parseLineTable();
		if (declFileNum <= 0 || declFileNum > fileList.size())
			return null;
		return fileList.get(declFileNum - 1);
	}
	
	private void ensureParsedForVariables() {
		if (!parsedForVarsAndAddresses) {
			DwarfInfoReader reader = new DwarfInfoReader(provider);
			reader.parseCompilationUnitForAddresses(this);
		}
	}
	
	/** ensure parsed for addresses before calling super.getScopeAtAddress()
	 * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#getScopeAtAddress(org.eclipse.cdt.core.IAddress)
	 */
	@Override
	public IScope getScopeAtAddress(IAddress linkAddress) {
		ensureParsedForAddresses();
		return super.getScopeAtAddress(linkAddress);
	}

	/**
	 * DwarfCompileUnit specific version of toString():<br>
	 * <code>
	 * [SymFile=, SectionOffset=, lowAddr=, highAddr=, path=, parsedForVarsAndAddress=, parsedForTypes=]
	 * </code>
	 * @see org.eclipse.cdt.debug.edc.internal.symbols.CompileUnitScope#toString()
	 */
	@Override
	public String toString() {
		StringBuilder builder = new StringBuilder();
		builder.append("DwarfCompileUnit [");
		
		builder.append("SymFile=");
		builder.append(provider.getSymbolFile().lastSegment());
		
		builder.append(", SectionOffset=0x");
		builder.append(Integer.toHexString(header.debugInfoOffset));
		
		builder.append(", lowAddr=");
		builder.append(lowAddress != null ? lowAddress.toHexAddressString() : null);
		
		builder.append(", highAddr=");
		builder.append(highAddress != null ? highAddress.toHexAddressString() : null);
		if (filePath != null) {
			builder.append(", path=");
			builder.append(filePath.toOSString());
		}
		builder.append(", parsedForVarsAndAddresses=");
		builder.append(parsedForVarsAndAddresses);
		builder.append(", parsedForTypes=");
		builder.append(parsedForTypes);
		builder.append("]\n");
		return builder.toString();
	}
	

	/**
	 * 1) calls super.addChild() first<br>
	 * 2) checks whether this has an empty range and merges range with passed child scope if not.<br>
	 * 3) adds line info to the passed child scope
	 * @see org.eclipse.cdt.debug.edc.internal.symbols.Scope#addChild(org.eclipse.cdt.debug.edc.symbols.IScope)
	 */
	@Override
	public void addChild(IScope scope) {
		super.addChild(scope);
		
		// if we don't know our scope yet...
		if (hasEmptyRange()) {
			rangesDirty = true;
		} else {
			// the CU may have an incomplete idea of its scope; fit the new scope in
			mergeScopeRange(scope);
		}

		addLineInfoToParent(scope);
	}

}
