/*=============================================================================#
 # 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.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.eclipse.statet.rj.data.RJIO;
import org.eclipse.statet.rj.data.RObject;
import org.eclipse.statet.rj.data.RObjectFactory;
import org.eclipse.statet.rj.data.impl.DefaultRObjectFactory;


/**
 * Command item for main loop data exchange/evaluation
 */
public final class DataCmdItem extends MainCmdItem {
	
	
	public static final class Operation {
		
		public static final byte NONE= 0;
		public static final byte EXPR= 1;
		public static final byte POINTER= 2;
		public static final byte FCALL= 3;
		public static final byte RDATA= 4;
		
		public final byte op;
		
		public final String name;
		
		public final byte source;
		public final byte target;
		public final boolean returnData;
		
		private final boolean reqSourceExpr;
		private final boolean reqRData;
		private final boolean reqTargetExpr;
		
		private Operation(final int op, final String name,
				final byte source, final byte target, final boolean returnData) {
			this.op= (byte)op;
			this.name= name;
			this.source= source;
			this.target= target;
			this.returnData= returnData;
			
			this.reqSourceExpr= (source == EXPR || source == POINTER || source == FCALL);
			this.reqRData= (source == FCALL || source == RDATA);
			this.reqTargetExpr= (target == EXPR || target == POINTER);
		}
		
		
		@Override
		public String toString() {
			return this.name;
		}
		
	}
	
	
	public static final byte EVAL_EXPR_VOID_OP=             0x01;
	public static final Operation EVAL_EXPR_VOID=           new Operation(EVAL_EXPR_VOID_OP, "EVAL_EXPR_VOID", //$NON-NLS-1$
			Operation.EXPR, Operation.NONE, false );
	public static final byte EVAL_FCALL_VOID_OP=            0x02;
	public static final Operation EVAL_FCALL_VOID=          new Operation(EVAL_FCALL_VOID_OP, "EVAL_FCALL_VOID", //$NON-NLS-1$
			Operation.FCALL, Operation.NONE, false );
	
	public static final byte EVAL_EXPR_DATA_OP=             0x03;
	public static final Operation EVAL_EXPR_DATA=           new Operation(EVAL_EXPR_DATA_OP, "EVAL_EXPR_DATA", //$NON-NLS-1$
			Operation.EXPR, Operation.NONE, true );
	public static final byte EVAL_FCALL_DATA_OP=            0x04;
	public static final Operation EVAL_FCALL_DATA=          new Operation(EVAL_FCALL_DATA_OP, "EVAL_FCALL_DATA", //$NON-NLS-1$
			Operation.FCALL, Operation.NONE, true );
	public static final byte RESOLVE_DATA_OP=               0x05;
	public static final Operation RESOLVE_DATA=             new Operation(RESOLVE_DATA_OP, "RESOLVE_DATA", // EVAL_REF_DATA //$NON-NLS-1$
			Operation.POINTER, Operation.NONE, true );
	
	public static final byte ASSIGN_DATA_OP=                0x06;
	public static final Operation ASSIGN_DATA=              new Operation(ASSIGN_DATA_OP, "ASSIGN_DATA", //$NON-NLS-1$
			Operation.RDATA, Operation.EXPR, false );
	public static final byte ASSIGN_FCALL_OP=               0x07;
	public static final Operation ASSIGN_FCALL=             new Operation(ASSIGN_FCALL_OP, "ASSIGN_FCALL", //$NON-NLS-1$
			Operation.FCALL, Operation.EXPR, false );
	
	public static final byte FIND_DATA_OP=                  0x08;
	public static final Operation FIND_DATA=                new Operation(FIND_DATA_OP, "FIND_DATA", //$NON-NLS-1$
			Operation.EXPR, Operation.NONE, true );
	
	public static final byte EVAL_NAMESPACE_DATA_OP=        0x09;
	public static final Operation EVAL_NAMESPACE_DATA=      new Operation(EVAL_NAMESPACE_DATA_OP, "EVAL_NAMESPACE_DATA", //$NON-NLS-1$
			Operation.EXPR, Operation.NONE, true );
	public static final byte EVAL_NAMESPACE_EXPORTS_DATA_OP= 0x0A;
	public static final Operation EVAL_NAMESPACE_EXPORTS_DATA= new Operation(EVAL_NAMESPACE_EXPORTS_DATA_OP, "EVAL_NAMESPACE_EXPORTS_DATA", //$NON-NLS-1$
			Operation.EXPR, Operation.NONE, true );
	
	
	private static final Operation[] OPERATIONS= new Operation[11];
	
	private static final void addOp(final Operation operation) {
		if (OPERATIONS[operation.op] != null) {
			throw new IllegalArgumentException();
		}
		OPERATIONS[operation.op]= operation;
	}
	
	private static final Operation getOperation(final byte op) {
		if (op <= 0 || op >= OPERATIONS.length) {
			throw new UnsupportedOperationException("data op: " + op); //$NON-NLS-1$
		}
		return OPERATIONS[op];
	}
	
	static {
		addOp(EVAL_EXPR_VOID);
		addOp(EVAL_FCALL_VOID);
		addOp(EVAL_EXPR_DATA);
		addOp(EVAL_FCALL_DATA);
		addOp(RESOLVE_DATA);
		addOp(ASSIGN_DATA);
		addOp(ASSIGN_FCALL);
		addOp(FIND_DATA);
		addOp(EVAL_NAMESPACE_DATA);
		addOp(EVAL_NAMESPACE_EXPORTS_DATA);
	}
	
	
	private static final int OV_WITHDATA=                  0x02000000;
	private static final int OV_WITHRHO=                   0x04000000;
	private static final int OV_WITHSTATUS=                0x08000000;
	
	
	public static final String DEFAULT_FACTORY_ID= "default"; //$NON-NLS-1$
	
	
	static RObjectFactory gDefaultFactory;
	
	static final Map<String, RObjectFactory> gFactories= new ConcurrentHashMap<>();
	
	private static final RObjectFactory getFactory(final String id) {
		final RObjectFactory factory= gFactories.get(id);
		if (factory != null) {
			return factory;
		}
		return gDefaultFactory;
	}
	
	static {
		RjsComConfig.setDefaultRObjectFactory(DefaultRObjectFactory.INSTANCE);
	}
	
	private static int checkCustomOptions(final int options) {
		if ((options & (RObjectFactory.F_WITH_DBG | RObjectFactory.F_ONLY_STRUCT)) == (RObjectFactory.F_WITH_DBG | RObjectFactory.F_ONLY_STRUCT)) {
			throw new IllegalArgumentException("options: RObjectFactory.F_LOAD_DBG & RObjectFactory.F_ONLY_STRUCT");
		}
		return (options & OM_CUSTOM);
	}
	
	
	private final Operation operation;
	
	private byte depth;
	private String sourceExpr;
	private String targetExpr;
	private RObject rdata;
	private RObject rho;
	
	private String factoryId;
	
	private RjsStatus status;
	
	
	/**
	 * Constructor for operations with returned data
	 */
	public DataCmdItem(final Operation op, final int options, final byte depth,
			final String sourceExpr, final RObject data, final String targetExpr,
			final RObject rho,
			final String factoryId) {
		assert (op.reqSourceExpr == (sourceExpr != null));
		assert (op.reqRData == (data != null));
		assert (op.reqTargetExpr == (targetExpr != null));
		assert (factoryId == null || gFactories.containsKey(factoryId));
		this.operation= op;
		this.sourceExpr= sourceExpr;
		this.targetExpr= targetExpr;
		this.options= (OV_WAITFORCLIENT | checkCustomOptions(options));
		if (data != null) {
			this.rdata= data;
			this.options |= OV_WITHDATA;
		}
		if (rho != null) {
			this.rho= rho;
			this.options |= OV_WITHRHO;
		}
		this.depth= depth;
		this.factoryId= (factoryId != null) ? factoryId : DEFAULT_FACTORY_ID;
	}
	
	/**
	 * Constructor for operations without returned data:
	 */
	public DataCmdItem(final Operation op, final int options,
			final String sourceExpr, final RObject data, final String targetExpr,
			final RObject rho) {
		assert (op.reqSourceExpr == (sourceExpr != null));
		assert (op.reqRData == (data != null));
		assert (op.reqTargetExpr == (targetExpr != null));
		this.operation= op;
		this.sourceExpr= sourceExpr;
		this.targetExpr= targetExpr;
		this.options= (OV_WAITFORCLIENT | checkCustomOptions(options));
		if (data != null) {
			this.rdata= data;
			this.options |= OV_WITHDATA;
		}
		if (rho != null) {
			this.rho= rho;
			this.options |= OV_WITHRHO;
		}
		this.factoryId= "";
	}
	
	
	/**
	 * Constructor for deserialization
	 */
	public DataCmdItem(final RJIO in) throws IOException {
		this.requestId= in.readInt();
		this.operation= getOperation(in.readByte());
		this.options= in.readInt();
		if ((this.options & OV_WITHSTATUS) != 0) {
			this.status= new RjsStatus(in);
			return;
		}
		this.depth= in.readByte();
		this.factoryId= in.readString();
		if ((this.options & OV_ANSWER) == 0) { // request
			if (this.operation.reqSourceExpr) {
				this.sourceExpr= in.readString();
			}
			if (this.operation.reqRData) {
				in.flags= 0;
				this.rdata= gDefaultFactory.readObject(in);
			}
			if (this.operation.reqTargetExpr) {
				this.targetExpr= in.readString();
			}
			if ((this.options & OV_WITHRHO) != 0) {
				in.flags= 0;
				this.rho= gDefaultFactory.readObject(in);
			}
		}
		else { // answer
			if ((this.options & OV_WITHDATA) != 0) {
				in.flags= (this.options & 0xff);
				this.rdata= getFactory(this.factoryId).readObject(in);
			}
			if ((this.options & OV_WITHRHO) != 0) {
				in.flags= RObjectFactory.F_ONLY_STRUCT;
				this.rho= getFactory(this.factoryId).readObject(in);
			}
		}
	}
	
	@Override
	public void writeExternal(final RJIO out) throws IOException {
		out.writeInt(this.requestId);
		out.writeByte(this.operation.op);
		out.writeInt(this.options);
		if ((this.options & OV_WITHSTATUS) != 0) {
			this.status.writeExternal(out);
			return;
		}
		out.writeByte(this.depth);
		out.writeString(this.factoryId);
		if ((this.options & OV_ANSWER) == 0) { // request
			if (this.operation.reqSourceExpr) {
				out.writeString(this.sourceExpr);
			}
			if (this.operation.reqRData) {
				out.flags= 0;
				gDefaultFactory.writeObject(this.rdata, out);
			}
			if (this.operation.reqTargetExpr) {
				out.writeString(this.targetExpr);
			}
			if ((this.options & OV_WITHRHO) != 0) {
				out.flags= 0;
				gDefaultFactory.writeObject(this.rho, out);
			}
		}
		else { // anwser
			if ((this.options & OV_WITHDATA) != 0) {
				out.flags= (this.options & 0xff);
				gDefaultFactory.writeObject(this.rdata, out);
			}
			if ((this.options & OV_WITHRHO) != 0) {
				out.flags= RObjectFactory.F_ONLY_STRUCT;
				gDefaultFactory.writeObject(this.rho, out);
			}
		}
	}
	
	
	@Override
	public byte getCmdType() {
		return T_DATA_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.sourceExpr= null;
			this.rdata= null;
			this.targetExpr= null;
			this.rho= null;
		}
		else {
			this.options= ((this.options & OM_CLEARFORANSWER) | (OV_ANSWER | OV_WITHSTATUS));
			this.status= status;
			this.sourceExpr= null;
			this.rdata= null;
			this.targetExpr= null;
			this.rho= null;
		}
	}
	
	public void setAnswer(final RObject rdata, final RObject rho) {
		this.options= ((this.options & OM_CLEARFORANSWER) | OV_ANSWER);
		if (rdata != null) {
			this.options |= OV_WITHDATA;
		}
		if (rho != null) {
			this.options |= OV_WITHRHO;
		}
		this.status= null;
		this.sourceExpr= null;
		this.rdata= rdata;
		this.targetExpr= null;
		this.rho= rho;
	}
	
	
	@Override
	public byte getOp() {
		return this.operation.op;
	}
	
	public Operation getOperation() {
		return this.operation;
	}
	
	@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 this.sourceExpr;
	}
	
	public RObject getData() {
		return this.rdata;
	}
	
	public String getTargetExpr() {
		return this.targetExpr;
	}
	
	public RObject getRho() {
		return this.rho;
	}
	
	public byte getDepth() {
		return this.depth;
	}
	
	
	@Override
	public boolean testEquals(final MainCmdItem other) {
		if (other instanceof DataCmdItem) {
			final DataCmdItem otherItem= (DataCmdItem) other;
			if (getOp() != otherItem.getOp()) {
				return false;
			}
			if (this.options != otherItem.options) {
				return false;
			}
			if (!((this.sourceExpr != null) ?
					this.sourceExpr.equals(otherItem.sourceExpr) :
					null == otherItem.sourceExpr )) {
				return false;
			}
			if (!((this.rdata != null) ?
					this.rdata.equals(otherItem.rdata) :
					null == otherItem.rdata )) {
				return false;
			}
			if (!((this.targetExpr != null) ?
					this.targetExpr.equals(otherItem.targetExpr) :
					null == otherItem.targetExpr )) {
				return false;
			}
			if (!((this.rho != null) ?
					this.rho.equals(otherItem.rho) :
					null == otherItem.rho )) {
				return false;
			}
			return true;
		}
		return false;
	}
	
	@Override
	public String toString() {
		final StringBuffer sb= new StringBuffer(100);
		sb.append("DataCmdItem ");
		sb.append(this.operation.name);
		sb.append("\n\t").append("options= 0x").append(Integer.toHexString(this.options));
		if (this.sourceExpr != null) {
			sb.append("\n<SOURCE-EXPR>\n");
			sb.append(this.sourceExpr);
			sb.append("\n</SOURCE-EXPR>");
		}
		else {
			sb.append("\n<SOURCE-EXPR/>");
		}
		if ((this.options & OV_WITHDATA) != 0) {
			sb.append("\n<DATA>\n");
			sb.append(this.rdata);
			sb.append("\n</DATA>");
		}
		else {
			sb.append("\n<DATA/>");
		}
		if (this.targetExpr != null) {
			sb.append("\n<TARGET-EXPR>\n");
			sb.append(this.targetExpr);
			sb.append("\n</TARGET-EXPR>");
		}
		else {
			sb.append("\n<TARGET-EXPR/>");
		}
		if ((this.options & OV_WITHRHO) != 0) {
			sb.append("\n<RHO>\n");
			sb.append(this.rho);
			sb.append("\n</RHO>");
		}
		if ((this.options & OV_WITHSTATUS) != 0) {
			sb.append("\n<STATUS>\n");
			sb.append(this.status);
			sb.append("\n</STATUS>");
		}
		return sb.toString();
	}
	
}
