/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.sysds.runtime.controlprogram.federated;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.apache.sysds.api.DMLScript;
import org.apache.sysds.utils.Statistics;

public class FederatedRequest implements Serializable {
	private static final long serialVersionUID = 5946781306963870394L;
	
	// commands sent to and excuted by federated workers
	public enum RequestType {
		READ_VAR,  // create variable for local data, read on first access
		PUT_VAR,   // receive data from main and store to local variable
		GET_VAR,   // return local variable to main
		EXEC_INST, // execute arbitrary instruction over
		EXEC_UDF,  // execute arbitrary user-defined function
	}
	
	private RequestType _method;
	private long _id;
	private List<Object> _data;
	private boolean _checkPrivacy;
	
	
	public FederatedRequest(RequestType method) {
		this(method, FederationUtils.getNextFedDataID(), new ArrayList<>());
	}
	
	public FederatedRequest(RequestType method, long id) {
		this(method, id, new ArrayList<>());
	}
	
	public FederatedRequest(RequestType method, long id, Object ... data) {
		this(method, id, Arrays.asList(data));
	}
	
	public FederatedRequest(RequestType method, long id, List<Object> data) {
		Statistics.incFederated(method);
		_method = method;
		_id = id;
		_data = data;
		setCheckPrivacy();
	}
	
	public RequestType getType() {
		return _method;
	}
	
	public long getID() {
		return _id;
	}
	
	public Object getParam(int i) {
		return _data.get(i);
	}
	
	public FederatedRequest appendParam(Object obj) {
		_data.add(obj);
		return this;
	}
	
	public FederatedRequest appendParams(Object ... objs) {
		_data.addAll(Arrays.asList(objs));
		return this;
	}
	
	public int getNumParams() {
		return _data.size();
	}
	
	public FederatedRequest deepClone() {
		return new FederatedRequest(_method, _id, new ArrayList<>(_data));
	}

	public void setCheckPrivacy(boolean checkPrivacy){
		this._checkPrivacy = checkPrivacy;
	}

	public void setCheckPrivacy(){
		setCheckPrivacy(DMLScript.CHECK_PRIVACY);
	}

	public boolean checkPrivacy(){
		return _checkPrivacy;
	}
	
	@Override
	public String toString() {
		StringBuilder sb = new StringBuilder("FederatedRequest[");
		sb.append(_method); sb.append(";");
		sb.append(_id); sb.append(";");
		sb.append(Arrays.toString(_data.toArray())); sb.append("]");
		return sb.toString();
	}
}
