/*=============================================================================#
 # Copyright (c) 2008, 2020 Stephan Wahlbrink and others.
 # 
 # This program and the accompanying materials are made available under the
 # terms of the Eclipse Public License 2.0 which is available at
 # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
 # which is available at https://www.apache.org/licenses/LICENSE-2.0.
 # 
 # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
 # 
 # Contributors:
 #     Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation
 #=============================================================================*/

package org.eclipse.statet.rj.server;

import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import java.util.List;

import org.eclipse.statet.jcommons.collections.ImCollections;

import org.eclipse.statet.rj.data.RJIO;
import org.eclipse.statet.rj.data.RJIOExternalizable;
import org.eclipse.statet.rj.server.dbg.CallStack;
import org.eclipse.statet.rj.server.dbg.CtrlReport;
import org.eclipse.statet.rj.server.dbg.DbgEnablement;
import org.eclipse.statet.rj.server.dbg.DbgFilterState;
import org.eclipse.statet.rj.server.dbg.DbgRequest;
import org.eclipse.statet.rj.server.dbg.ElementTracepointInstallationRequest;
import org.eclipse.statet.rj.server.dbg.FlagTracepointInstallationRequest;
import org.eclipse.statet.rj.server.dbg.FrameContext;
import org.eclipse.statet.rj.server.dbg.FrameContextDetailRequest;
import org.eclipse.statet.rj.server.dbg.SetDebugReport;
import org.eclipse.statet.rj.server.dbg.SetDebugRequest;
import org.eclipse.statet.rj.server.dbg.TracepointEvent;
import org.eclipse.statet.rj.server.dbg.TracepointStatesUpdate;


/**
 * Command item for main loop dbg operations (="op")
 */
public final class DbgCmdItem extends MainCmdItem implements RjsComObject, Externalizable {
	
	// -- C2S sync
	public static final byte OP_LOAD_FRAME_LIST=            0001;
	public static final byte OP_LOAD_FRAME_CONTEXT=         0002;
	public static final byte OP_SET_DEBUG=                  0003;
	public static final byte OP_REQUEST_SUSPEND=            0004;
//	public static final byte OP_CTRL_SUSPEND=               0010;
	public static final byte OP_CTRL_RESUME=                0011;
	public static final byte OP_CTRL_STEP_INTO=             0012;
	public static final byte OP_CTRL_STEP_OVER=             0014;
	public static final byte OP_CTRL_STEP_RETURN=           0016;
	public static final byte OP_INSTALL_TP_FLAGS=           0020;
	public static final byte OP_INSTALL_TP_POSITIONS=       0021;
	
	// -- C2S sync + async
	public static final byte OP_SET_ENABLEMENT=             0031;
	public static final byte OP_RESET_FILTER_STATE=         0032;
	public static final byte OP_UPDATE_TP_STATES=           0034;
	
	public static final byte OP_C2S_S2C=                    0040;
	
	public static final byte OP_NOTIFY_TP_EVENTS=           0x41;
	
	
	private static final int OV_WITHDATA=                   0x01000000;
	private static final int OV_WITHSTATUS=                 0x08000000;
	
	
	private static Object readRequestData(final RJIO io, final byte type) throws IOException {
		switch (type) {
		case OP_LOAD_FRAME_LIST:
			return null;
		case OP_LOAD_FRAME_CONTEXT:
			return new FrameContextDetailRequest(io);
		case OP_SET_DEBUG:
			return new SetDebugRequest(io);
		case OP_REQUEST_SUSPEND:
			return null;
		case OP_CTRL_RESUME:
			return new DbgRequest.Resume(io);
		case OP_CTRL_STEP_INTO:
			return new DbgRequest.StepInto(io);
		case OP_CTRL_STEP_OVER:
			return new DbgRequest.StepOver(io);
		case OP_CTRL_STEP_RETURN:
			return new DbgRequest.StepReturn(io);
		case OP_SET_ENABLEMENT:
			return new DbgEnablement(io);
		case OP_RESET_FILTER_STATE:
			return new DbgFilterState(io);
		case OP_INSTALL_TP_FLAGS:
			return new FlagTracepointInstallationRequest(io);
		case OP_INSTALL_TP_POSITIONS:
			return new ElementTracepointInstallationRequest(io);
		case OP_UPDATE_TP_STATES:
			return new TracepointStatesUpdate(io);
		case OP_NOTIFY_TP_EVENTS:
			return readTracepointEvents(io);
		default:
			break;
		}
		throw new IOException("Unsupported type= " + type); //$NON-NLS-1$
	}
	
	private static Object readAnswerData(final RJIO io, final byte type) throws IOException {
		switch (type) {
		case OP_LOAD_FRAME_LIST:
			return new CallStack(io);
		case OP_LOAD_FRAME_CONTEXT:
			return new FrameContext(io);
		case OP_SET_DEBUG:
			return new SetDebugReport(io);
		case OP_REQUEST_SUSPEND:
			break; // status
		case OP_CTRL_RESUME:
		case OP_CTRL_STEP_INTO:
		case OP_CTRL_STEP_OVER:
		case OP_CTRL_STEP_RETURN:
			return new CtrlReport(io);
		case OP_SET_ENABLEMENT:
		case OP_RESET_FILTER_STATE:
			break; // status
		case OP_INSTALL_TP_FLAGS:
		case OP_INSTALL_TP_POSITIONS:
		case OP_UPDATE_TP_STATES:
			break; // status
		default:
			break;
		}
		throw new IOException("Unsupported type= " + type); //$NON-NLS-1$
	}
	
	private static void writeList(final List<RJIOExternalizable> list, final RJIO io) throws IOException {
		final int l= list.size();
		io.writeInt(l);
		for (int i= 0; i < l; i++) {
			list.get(i).writeExternal(io);
		}
	}
	
	private static List<TracepointEvent> readTracepointEvents(final RJIO io) throws IOException {
		final TracepointEvent[] array= new TracepointEvent[io.readInt()];
		for (int i= 0; i < array.length; i++) {
			array[i]= new TracepointEvent(io);
		}
		return ImCollections.newList(array);
	}
	
	
	private byte op;
	
	private Object data;
	
	private RjsStatus status;
	
	
	/**
	 * Constructor for new commands
	 */
	public DbgCmdItem(final byte op, final int options,
			final RJIOExternalizable data) {
		this.op= op;
		this.options= (options & OM_CUSTOM);
		if (data != null) {
			this.options |= OV_WITHDATA;
		}
		if (op < OP_NOTIFY_TP_EVENTS) {
			this.options |= OV_WAITFORCLIENT;
		}
		this.data= data;
	}
	
	/**
	 * Constructor for new commands
	 */
	public DbgCmdItem(final byte op, final int options,
			final List<? extends RJIOExternalizable> data) {
		assert (op == OP_NOTIFY_TP_EVENTS);
		this.op= op;
		this.options= (options & OM_CUSTOM);
		if (data != null) {
			this.options |= OV_WITHDATA;
		}
		if (op < OP_NOTIFY_TP_EVENTS) {
			this.options |= OV_WAITFORCLIENT;
		}
		this.data= data;
	}
	
	/**
	 * Constructor for automatic deserialization
	 */
	public DbgCmdItem() {
	}
	
	/**
	 * Constructor for deserialization
	 */
	public DbgCmdItem(final RJIO io) throws IOException {
		readExternal(io);
	}
	
	@Override
	public void writeExternal(final RJIO io) throws IOException {
		io.writeInt(this.options);
		io.writeByte(this.op);
		if ((this.options & OV_WITHSTATUS) != 0) {
			this.status.writeExternal(io);
		}
		else if ((this.options & OV_WITHDATA) != 0) {
			if (this.op == OP_NOTIFY_TP_EVENTS) {
				writeList((List<RJIOExternalizable>) this.data, io);
			}
			else {
				((RJIOExternalizable) this.data).writeExternal(io);
			}
		}
	}
	
	@Override
	public void writeExternal(final ObjectOutput out) throws IOException {
		final RJIO io= RJIO.get(out);
		final int check= io.writeCheck1();
		writeExternal(io);
		io.writeCheck2(check);
		io.disconnect(out);
	}
	
	private void readExternal(final RJIO io) throws IOException {
		this.options= io.readInt();
		this.op= io.readByte();
		if ((this.options & OV_WITHSTATUS) != 0) {
			this.status= new RjsStatus(io);
		}
		else if ((this.options & OV_WITHDATA) != 0) {
			this.data= ((this.options & OV_ANSWER) == 0) ?
					readRequestData(io, this.op) :
					readAnswerData(io, this.op);
		}
	}
	
	@Override
	public void readExternal(final ObjectInput in) throws IOException {
		final RJIO io= RJIO.get(in);
		final int check= io.readCheck1();
		readExternal(io);
		io.readCheck2(check);
		io.disconnect(in);
	}
	
	
	@Override
	public int getComType() {
		return T_DBG;
	}
	
	@Override
	public byte getCmdType() {
		return T_DBG_ITEM;
	}
	
	
	@Override
	public void setAnswer(final RjsStatus status) {
		assert (status != null);
		if (status == RjsStatus.OK_STATUS) {
			this.options= (this.options & OM_CLEARFORANSWER) | OV_ANSWER;
			this.status= null;
			this.data= null;
		}
		else {
			this.options= (this.options & OM_CLEARFORANSWER) | (OV_ANSWER | OV_WITHSTATUS);
			this.status= status;
			this.data= null;
		}
	}
	
	public void setAnswer(final RJIOExternalizable data) {
		this.options= (this.options & OM_CLEARFORANSWER) | OV_ANSWER;
		if (data != null) {
			this.options |= OV_WITHDATA;
		}
		this.status= null;
		this.data= data;
	}
	
	
	@Override
	public byte getOp() {
		return this.op;
	}
	
	@Override
	public boolean isOK() {
		return (this.status == null || this.status.getSeverity() == RjsStatus.OK);
	}
	
	@Override
	public RjsStatus getStatus() {
		return this.status;
	}
	
	@Override
	public String getDataText() {
		return null;
	}
	
	public Object getData() {
		return this.data;
	}
	
	
	@Override
	public boolean testEquals(final MainCmdItem other) {
		if (!(other instanceof DbgCmdItem)) {
			return false;
		}
		final DbgCmdItem otherItem= (DbgCmdItem) other;
		if (getOp() != otherItem.getOp()) {
			return false;
		}
		if (this.options != otherItem.options) {
			return false;
		}
		return true;
	}
	
	@Override
	public String toString() {
		final StringBuffer sb= new StringBuffer(100);
		sb.append("DbgCmdItem "); //$NON-NLS-1$
		switch (this.op) {
		case OP_LOAD_FRAME_LIST:
			sb.append("LOAD_FRAME_LIST"); //$NON-NLS-1$
			break;
		case OP_LOAD_FRAME_CONTEXT:
			sb.append("LOAD_FRAME_CONTEXT"); //$NON-NLS-1$
			break;
		case OP_SET_DEBUG:
			sb.append("SET_DEBUG"); //$NON-NLS-1$
			break;
		case OP_REQUEST_SUSPEND:
			sb.append("REQUEST_SUSPEND"); //$NON-NLS-1$
			break;
		case OP_CTRL_RESUME:
			sb.append("CTRL_RESUME"); //$NON-NLS-1$
			break;
		case OP_CTRL_STEP_INTO:
			sb.append("CTRL_STEP_INTO"); //$NON-NLS-1$
			break;
		case OP_CTRL_STEP_OVER:
			sb.append("CTRL_STEP_OVER"); //$NON-NLS-1$
			break;
		case OP_CTRL_STEP_RETURN:
			sb.append("CTRL_STEP_RETURN"); //$NON-NLS-1$
			break;
		case OP_INSTALL_TP_FLAGS:
			sb.append("INSTALL_TP_FLAGS"); //$NON-NLS-1$
			break;
		case OP_INSTALL_TP_POSITIONS:
			sb.append("INSTALL_TP_POSITIONS"); //$NON-NLS-1$
			break;
		case OP_SET_ENABLEMENT:
			sb.append("SET_ENABLEMENT"); //$NON-NLS-1$
			break;
		case OP_RESET_FILTER_STATE:
			sb.append("RESET_FILTER_STATE"); //$NON-NLS-1$
			break;
		case OP_UPDATE_TP_STATES:
			sb.append("UPDATE_TP_STATES"); //$NON-NLS-1$
			break;
		case OP_NOTIFY_TP_EVENTS:
			sb.append("NOTIFY_TP_EVENT"); //$NON-NLS-1$
			break;
		default:
			sb.append(this.op);
			break;
		}
		sb.append("\n\t" + "options= 0x").append(Integer.toHexString(this.options)); //$NON-NLS-1$ //$NON-NLS-2$
		if ((this.options & OV_WITHDATA) != 0) {
			sb.append("\n<DATA>\n"); //$NON-NLS-1$
			sb.append(this.data);
			sb.append("\n</DATA>"); //$NON-NLS-1$
		}
		return sb.toString();
	}
	
}
