/*******************************************************************************
 * Copyright (c) 2004, 2009 IBM Corporation 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:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.ant.internal.launching.debug.model;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugException;
import org.eclipse.debug.core.model.IBreakpoint;
import org.eclipse.debug.core.model.IStackFrame;
import org.eclipse.debug.core.model.IThread;
import org.eclipse.debug.core.model.IVariable;

/**
 * An Ant build thread.
 */
public class AntThread extends AntDebugElement implements IThread {
	
	/**
	 * Breakpoints this thread is suspended at or <code>null</code>
	 * if none.
	 */
	private IBreakpoint[] fBreakpoints;
	
	/**
	 * The stackframes associated with this thread
	 */
	private List fFrames= new ArrayList(1);
	
	/**
	 * The stackframes to be reused on suspension
	 */
	private List fOldFrames;
	
	/**
	 * Whether this thread is stepping
	 */
	private boolean fStepping = false;
	
	private boolean fRefreshProperties= true;
	
	/**
	 * The user properties associated with this thread
	 */
	private AntProperties fUserProperties;
	
	/**
	 * The system properties associated with this thread
	 */
	private AntProperties fSystemProperties;
	
	/**
	 * The properties set during the build associated with this thread
	 */
	private AntProperties fRuntimeProperties;
    
    private Object fPropertiesLock= new Object();
	
	/**
	 * Constructs a new thread for the given target
	 * 
	 * @param target the Ant Build
	 */
	public AntThread(AntDebugTarget target) {
		super(target);
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getStackFrames()
	 */
	public synchronized IStackFrame[] getStackFrames() throws DebugException {
		if (isSuspended()) {
			if (fFrames.size() == 0) {
				getStackFrames0();
			}
		} 
		
		return (IStackFrame[]) fFrames.toArray(new IStackFrame[fFrames.size()]);
	}
	
	/**
	 * Retrieves the current stack frames in the thread
	 * possibly waiting until the frames are populated
     * 
	 */
	private void getStackFrames0() throws DebugException {
        synchronized (fFrames) {
    		getAntDebugTarget().getStackFrames();
            if (fFrames.size() > 0) {
                //frames set..no need to wait
                return;
            }
            int attempts= 0;
    		try {
                while (fFrames.size() == 0 && !isTerminated()) {
                    fFrames.wait(50);
                    if (attempts == 20 && fFrames.size() == 0 && !isTerminated()) {
                        throwDebugException(DebugModelMessages.AntThread_3);
                    }
                    attempts++;
                }
    		} catch (InterruptedException e) {
    		}
        }
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#hasStackFrames()
	 */
	public boolean hasStackFrames() throws DebugException {
		return isSuspended();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getPriority()
	 */
	public int getPriority() throws DebugException {
		return 0;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getTopStackFrame()
	 */
	public synchronized IStackFrame getTopStackFrame() throws DebugException {
		if (isSuspended()) {
			if (fFrames.size() == 0) {
				getStackFrames0();
			}
			if (fFrames.size() > 0) {
				return (IStackFrame)fFrames.get(0);
			}
		} 
		return null;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getName()
	 */
	public String getName() {
		return "Thread [Ant Build]"; //$NON-NLS-1$
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IThread#getBreakpoints()
	 */
	public IBreakpoint[] getBreakpoints() {
		if (fBreakpoints == null) {
			return new IBreakpoint[0];
		}
		return fBreakpoints;
	}
	
	/**
	 * Sets the breakpoints this thread is suspended at, or <code>null</code>
	 * if none.
	 * 
	 * @param breakpoints the breakpoints this thread is suspended at, or <code>null</code>
	 * if none
	 */
	protected void setBreakpoints(IBreakpoint[] breakpoints) {
		fBreakpoints = breakpoints;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#canResume()
	 */
	public boolean canResume() {
		return isSuspended();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#canSuspend()
	 */
	public boolean canSuspend() {
		return !isSuspended();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#isSuspended()
	 */
	public boolean isSuspended() {
		return getDebugTarget().isSuspended();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#resume()
	 */
	public synchronized void resume() throws DebugException {
		aboutToResume(DebugEvent.CLIENT_REQUEST, false);
		getDebugTarget().resume();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ISuspendResume#suspend()
	 */
	public synchronized void suspend() throws DebugException {
		getDebugTarget().suspend();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#canStepInto()
	 */
	public boolean canStepInto() {
	    return isSuspended();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#canStepOver()
	 */
	public boolean canStepOver() {
		return isSuspended();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#canStepReturn()
	 */
	public boolean canStepReturn() {
		return false;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#isStepping()
	 */
	public boolean isStepping() {
		return fStepping;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#stepInto()
	 */
	public synchronized void stepInto() throws DebugException {
	    aboutToResume(DebugEvent.STEP_INTO, true);
		((AntDebugTarget)getDebugTarget()).stepInto();
	}
	
	private void aboutToResume(int detail, boolean stepping) {
	    fRefreshProperties= true;
	    fOldFrames= new ArrayList(fFrames);
        fFrames.clear();
        setPropertiesValid(false);
	    setStepping(stepping);
	    setBreakpoints(null);
		fireResumeEvent(detail);
    }

    private void setPropertiesValid(boolean valid) {
        if (fUserProperties != null) {
            fUserProperties.setValid(valid);
            fSystemProperties.setValid(valid);
            fRuntimeProperties.setValid(valid);
        }
    }

    /* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#stepOver()
	 */
	public synchronized void stepOver() throws DebugException {
	    aboutToResume(DebugEvent.STEP_OVER, true);
		((AntDebugTarget)getDebugTarget()).stepOver();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.IStep#stepReturn()
	 */
	public synchronized void stepReturn() throws DebugException {
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ITerminate#canTerminate()
	 */
	public boolean canTerminate() {
		return !isTerminated();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ITerminate#isTerminated()
	 */
	public boolean isTerminated() {
		return getDebugTarget().isTerminated();
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.debug.core.model.ITerminate#terminate()
	 */
	public void terminate() throws DebugException {
		fFrames.clear();
		getDebugTarget().terminate();
	}
	
	/**
	 * Sets whether this thread is stepping
	 * 
	 * @param stepping whether stepping
	 */
	protected void setStepping(boolean stepping) {
		fStepping = stepping;
	}

    public void buildStack(String data) { 
        synchronized (fFrames) {
            String[] strings= data.split(DebugMessageIds.MESSAGE_DELIMITER);
            //0 STACK message
            //1 targetName
            //2 taskName
            //3 filePath
            //4 lineNumber
            //5 ...
            if (fOldFrames != null && (strings.length - 1)/ 4 != fOldFrames.size()) {
                fOldFrames= null; //stack size changed..do not preserve
            }
            StringBuffer name;
            String filePath;
            int lineNumber;
            int stackFrameId= 0;
            String taskName;
            for (int i = 1; i < strings.length; i++) {
                if (strings[i].length() > 0) {
                    name= new StringBuffer(strings[i]);
                    taskName= strings[++i];
                    if (taskName.length() > 0) {
                        name.append(": "); //$NON-NLS-1$
                        name.append(taskName);
                    }
                } else {
                    name= new StringBuffer(strings[++i]);
                }
                filePath= strings[++i];
                lineNumber= Integer.parseInt(strings[++i]);
                addFrame(stackFrameId++, name.toString(), filePath, lineNumber);
            }
            //wake up the call from getStackFrames
            fFrames.notifyAll();
        }
    }
    
    private void addFrame(int stackFrameId, String name, String filePath, int lineNumber) {
    	AntStackFrame frame= getOldFrame();
    	
    	if (frame == null || !frame.getFilePath().equals(filePath)) {
    		frame= new AntStackFrame(this, stackFrameId, name, filePath, lineNumber);
    	} else {
    		frame.setFilePath(filePath);
    		frame.setId(stackFrameId);
    		frame.setLineNumber(lineNumber);
    		frame.setName(name);
    	}
		fFrames.add(frame);
    }
    
    private AntStackFrame getOldFrame() {
    	if (fOldFrames == null) {
    		return null;
    	}
    	AntStackFrame frame= (AntStackFrame) fOldFrames.remove(0);
    	if (fOldFrames.isEmpty()) {
    		fOldFrames= null;
    	}
    	return frame;
    }
    
    public void newProperties(String data) {
        synchronized (fPropertiesLock) {
            try {
                String[] datum= data.split(DebugMessageIds.MESSAGE_DELIMITER);
                if (fUserProperties == null) {
                    initializePropertyGroups();
                }

                List userProperties= ((AntPropertiesValue)fUserProperties.getLastValue()).getProperties();
                List systemProperties= ((AntPropertiesValue)fSystemProperties.getLastValue()).getProperties();
                List runtimeProperties= ((AntPropertiesValue)fRuntimeProperties.getLastValue()).getProperties();
                //0 PROPERTIES message
                //1 propertyName length
                //2 propertyName
                //3 propertyValue length
                //3 propertyValue
                //4 propertyType
                //5 ...
                if (datum.length > 1) { //new properties
                    StringBuffer propertyName;
                    StringBuffer propertyValue;
                    int propertyNameLength;
                    int propertyValueLength;
                    for (int i = 1; i < datum.length; i++) {
                        propertyNameLength= Integer.parseInt(datum[i]);
                        propertyName= new StringBuffer(datum[++i]);
                        while (propertyName.length() != propertyNameLength) {
                            propertyName.append(DebugMessageIds.MESSAGE_DELIMITER);
                            propertyName.append(datum[++i]);
                        }

                        propertyName= getAntDebugTarget().getAntDebugController().unescapeString(propertyName);

                        propertyValueLength= Integer.parseInt(datum[++i]);
                        if (propertyValueLength == 0 && i + 1 == datum.length) { //bug 81299
                            propertyValue= new StringBuffer(""); //$NON-NLS-1$
                        } else {
                            propertyValue= new StringBuffer(datum[++i]);
                        }
                        while (propertyValue.length() != propertyValueLength) {
                            propertyValue.append(DebugMessageIds.MESSAGE_DELIMITER);
                            propertyValue.append(datum[++i]);
                        }

                        propertyValue= getAntDebugTarget().getAntDebugController().unescapeString(propertyValue);

                        int propertyType= Integer.parseInt(datum[++i]);
                        addProperty(userProperties, systemProperties, runtimeProperties, propertyName.toString(), propertyValue.toString(), propertyType);
                    }
                }
            } finally {
                fRefreshProperties= false;
                setPropertiesValid(true);
                //wake up the call from getVariables
                fPropertiesLock.notifyAll();
            }
        }
	}

	private void addProperty(List userProperties, List systemProperties, List runtimeProperties, String propertyName, String propertyValue, int propertyType) {
		AntProperty property= new AntProperty((AntDebugTarget) getDebugTarget(), propertyName, propertyValue);
		switch (propertyType) {
			case DebugMessageIds.PROPERTY_SYSTEM:
				systemProperties.add(property);
				break;
			case DebugMessageIds.PROPERTY_USER:
				userProperties.add(property);
				break;
			case DebugMessageIds.PROPERTY_RUNTIME:
				runtimeProperties.add(property);
				break;
		}
	}

	private void initializePropertyGroups() {
        AntDebugTarget target= getAntDebugTarget();
		fUserProperties= new AntProperties(target, DebugModelMessages.AntThread_0);
		fUserProperties.setValue(new AntPropertiesValue(target));
		fSystemProperties= new AntProperties(target, DebugModelMessages.AntThread_1);
		fSystemProperties.setValue(new AntPropertiesValue(target));
		fRuntimeProperties= new AntProperties(target, DebugModelMessages.AntThread_2);
		fRuntimeProperties.setValue(new AntPropertiesValue(target));
	}
    
    protected IVariable[] getVariables() throws DebugException {
        synchronized (fPropertiesLock) {
            if (fRefreshProperties) {
                getAntDebugTarget().getProperties();
                if (fRefreshProperties) { 
                    //properties have not been set; need to wait
                    try {
                        int attempts= 0;
                        while (fRefreshProperties && !isTerminated()) {
                            fPropertiesLock.wait(50);
                            if (attempts == 20 && fRefreshProperties && !isTerminated()) {
                                throwDebugException(DebugModelMessages.AntThread_4);
                            }
                            attempts++;
                        }
                    } catch (InterruptedException ie) {
                    }
                }
            }
            if (fSystemProperties == null) {
                return new IVariable[0];
            }
            return new IVariable[]{fSystemProperties, fUserProperties, fRuntimeProperties};
        }
    }
}