/*=============================================================================#
 # Copyright (c) 2008, 2021 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;
	
	// -- S2C sync
	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();
	}
	
}
