/*******************************************************************************
 * Copyright (c) 2010 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.wst.jsdt.debug.internal.chrome.jsdi;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.eclipse.osgi.util.NLS;
import org.eclipse.wst.jsdt.debug.core.jsdi.BooleanValue;
import org.eclipse.wst.jsdt.debug.core.jsdi.NullValue;
import org.eclipse.wst.jsdt.debug.core.jsdi.NumberValue;
import org.eclipse.wst.jsdt.debug.core.jsdi.StringValue;
import org.eclipse.wst.jsdt.debug.core.jsdi.UndefinedValue;
import org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine;
import org.eclipse.wst.jsdt.debug.core.jsdi.event.EventQueue;
import org.eclipse.wst.jsdt.debug.core.jsdi.request.EventRequestManager;
import org.eclipse.wst.jsdt.debug.internal.chrome.ChromePlugin;
import org.eclipse.wst.jsdt.debug.internal.chrome.Tracing;
import org.eclipse.wst.jsdt.debug.internal.chrome.event.EventQueueImpl;
import org.eclipse.wst.jsdt.debug.internal.chrome.request.EventReqManager;
import org.eclipse.wst.jsdt.debug.internal.chrome.transport.Attributes;
import org.eclipse.wst.jsdt.debug.internal.chrome.transport.EventPacketImpl;
import org.eclipse.wst.jsdt.debug.internal.chrome.transport.RequestPacketImpl;
import org.eclipse.wst.jsdt.debug.internal.chrome.transport.Commands;
import org.eclipse.wst.jsdt.debug.internal.chrome.transport.JSON;
import org.eclipse.wst.jsdt.debug.transport.DebugSession;
import org.eclipse.wst.jsdt.debug.transport.exception.DisconnectedException;
import org.eclipse.wst.jsdt.debug.transport.exception.TimeoutException;
import org.eclipse.wst.jsdt.debug.transport.packet.Event;
import org.eclipse.wst.jsdt.debug.transport.packet.Request;
import org.eclipse.wst.jsdt.debug.transport.packet.Response;

/**
 * Default implementation of a {@link VirtualMachine} for Chrome
 * 
 * @since 1.0
 */
public class VMImpl extends MirrorImpl implements VirtualMachine {

	public static int RUNNING = 1;
	public static int SUSPENDED = 2;
	public static int TERMINATED = 3;
	public static int DISPOSED = 4;
	public static int DISCONNECTED = 5;
	
	/**
	 * The current state
	 */
	private int state = 0;
	/**
	 * The singleton {@link NullValue}
	 */
	private static NullValue nullValue = null;
	/**
	 * The singleton {@link UndefinedValue}
	 */
	private static UndefinedValue undefinedValue = null;
	
	private EventRequestManager ermanager = new EventReqManager(this);
	private EventQueue queue = new EventQueueImpl(this, ermanager);
	private final DebugSession session;
	
	private Map threads = null;
	private Map scripts = null;
	private String version = null;
	
	/**
	 * Constructor
	 * 
	 * @param session the backing {@link DebugSession}
	 */
	public VMImpl(DebugSession session) {
		super();
		this.session = session;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#resume()
	 */
	public synchronized void resume() {
		if(state == SUSPENDED) {
			//TODO
			state = RUNNING;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#suspend()
	 */
	public synchronized void suspend() {
		if(state == RUNNING) {
			//TODO
			state = SUSPENDED;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#terminate()
	 */
	public synchronized void terminate() {
		if(state != TERMINATED) {
			//TODO
			state = TERMINATED;
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#name()
	 */
	public String name() {
		return NLS.bind(Messages.chrome_vm, version());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#description()
	 */
	public String description() {
		return Messages.vm_description;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#version()
	 */
	public synchronized String version() {
		if(version == null) {
			RequestPacketImpl request = new RequestPacketImpl(Commands.VERSION, Attributes.TOOL_DEVTOOLSRVC, null);
			Response response = sendRequest(request);
			if(response.isSuccess()) {
				version = (String) response.getBody().get(Attributes.DATA);
			}
			else if(TRACE) {
				Tracing.writeString("VM [failed version request]" + JSON.serialize(request)); //$NON-NLS-1$
			}
		}
		return version;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#allThreads()
	 */
	public synchronized List allThreads() {
		if(threads == null) {
			threads = Collections.synchronizedMap(new HashMap(4));
			RequestPacketImpl request = new RequestPacketImpl(Commands.LIST_TABS, Attributes.TOOL_DEVTOOLSRVC, null);
			Response response = sendRequest(request);
			if(response.isSuccess()) {
				List tabs = (List) response.getBody().get(Attributes.DATA);
				if(tabs != null) {
					ArrayList values = null;
					for(Iterator i = tabs.iterator(); i.hasNext();) {
						values = (ArrayList) i.next();
						String url = (String)values.get(1);
						Number id = (Number)values.get(0);
						ThreadImpl thread = new ThreadImpl(this, id, url);
						threads.put(id, thread);
						attach(thread);
					}
				}
			}
			else if(TRACE) {
				Tracing.writeString("VM [failed all_tabs request]" + JSON.serialize(request)); //$NON-NLS-1$
			}
		}
		return new ArrayList(threads.values());
	}

	/**
	 * Try to attach the debugger to the v8 debugger service for the given thread (tab)
	 * 
	 * @param thread
	 */
	void attach(ThreadImpl thread) {
		RequestPacketImpl request = new RequestPacketImpl(Commands.ATTACH, Attributes.TOOL_DEVTOOLSRVC, thread.id());
		Response response = sendRequest(request);
		if(response.isSuccess()) {
			
		}
		else if(TRACE) {
			Tracing.writeString("VM [failed attach request] " + JSON.serialize(request)); //$NON-NLS-1$
		}
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#allScripts()
	 */
	public synchronized List allScripts() {
		if(this.scripts == null) {
			this.scripts = Collections.synchronizedMap(new HashMap(4));
		}
		return new ArrayList(scripts.values());
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#dispose()
	 */
	public synchronized void dispose() {
		if(state != DISPOSED) {
			//TODO
			try {
				if(threads != null) {
					threads.clear();
					threads = null;
				}
				if(scripts != null) {
					scripts.clear();
					scripts = null;
				}
			}
			finally {
				state = DISPOSED;
			}
		}
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#mirrorOfUndefined()
	 */
	public UndefinedValue mirrorOfUndefined() {
		synchronized (this) {
			if(undefinedValue == null) {
				undefinedValue = new UndefinedImpl(this);
			}
		}
		return undefinedValue;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#mirrorOfNull()
	 */
	public NullValue mirrorOfNull() {
		synchronized (this) {
			if(nullValue == null) {
				nullValue = new NullImpl(this);
			}
		}
		return nullValue;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#mirrorOf(boolean)
	 */
	public BooleanValue mirrorOf(boolean bool) {
		return new BooleanImpl(this, bool);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#mirrorOf(java.lang.Number)
	 */
	public NumberValue mirrorOf(Number number) {
		return new NumberImpl(this, number);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#mirrorOf(java.lang.String)
	 */
	public StringValue mirrorOf(String string) {
		return new StringImpl(this, string);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#eventRequestManager()
	 */
	public EventRequestManager eventRequestManager() {
		return ermanager;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.wst.jsdt.debug.core.jsdi.VirtualMachine#eventQueue()
	 */
	public EventQueue eventQueue() {
		return queue;
	}
	
	/**
	 * Sends a request to the underlying {@link DebugSession}, waiting
	 * for the {@link VirtualMachine#DEFAULT_TIMEOUT}.
	 * 
	 * @param request
	 * @return the {@link CFResponse} for the request
	 */
	public Response sendRequest(Request request) {
		try {
			session.send(request);
			return session.receiveResponse(request.getSequence(), 3000);
		}
		catch(DisconnectedException de) {
			disconnectVM();
			handleException(de.getMessage(), de.getCause());
		}
		catch(TimeoutException te) {
			ChromePlugin.log(te);
		}
		return null;
	}
	
	/**
	 * Receives an {@link EventPacket} from the underlying {@link DebugSession}, 
	 * waiting for the {@link VirtualMachine#DEFAULT_TIMEOUT}.
	 * 
	 * @return the next {@link EventPacket} never <code>null</code>
	 * @throws TimeoutException
	 * @throws DisconnectedException
	 */
	public Event receiveEvent() throws TimeoutException, DisconnectedException {
		return (Event) session.receive(EventPacketImpl.EVENT, DEFAULT_TIMEOUT);
	}

	/**
	 * Receives an {@link EventPacket} from the underlying {@link DebugSession}, 
	 * waiting for the {@link VirtualMachine#DEFAULT_TIMEOUT}.
	 * @param timeout
	 * @return the next {@link EventPacket} never <code>null</code>
	 * @throws TimeoutException
	 * @throws DisconnectedException
	 */
	public Event receiveEvent(int timeout) throws TimeoutException, DisconnectedException {
		return (Event) session.receive(EventPacketImpl.EVENT, timeout);
	}
	
	/**
	 * disconnects the VM
	 */
	public synchronized void disconnectVM() {
		if (state == DISCONNECTED) {
			if(TRACE) {
				Tracing.writeString("VM [already disconnected]"); //$NON-NLS-1$
			}
			return;
		}
		if(TRACE) {
			Tracing.writeString("VM [disconnecting]"); //$NON-NLS-1$
		}
		try {
			if(threads != null) {
				threads.clear();
			}
			if(scripts != null) {
				scripts.clear();
			}
			this.session.dispose();
		} finally {
			state = DISCONNECTED;
		}
	}
}
