package simulator.interfaces.db;

import models.algebra.Constant;
import models.algebra.Expression;
import models.algebra.Term;
import models.dataConstraintModel.JsonTerm;
import models.dataConstraintModel.ResourcePath;
import models.dataFlowModel.DataTransferChannel;
import simulator.Event;
import simulator.Resource;
import simulator.ResourceIdentifier;
import simulator.Simulator;
import simulator.SystemState;
import simulator.interfaces.INativeReceiver;

public class DatabasePresenter implements INativeReceiver{

	public final String updateCurrentChannelName = "updateCurrent";
	public final String setRecordChannelName = "setRecord";
	public final String updateRecordChannelName = "updateRecordOnChangeCurrent";
	
	protected Simulator simulator;
	
	protected DataTransferChannel setRecordChannel;
	protected DataTransferChannel updateRecord;
	
	public DatabasePresenter(Simulator simulator) {
		this.simulator = simulator;
		setRecordChannel = (DataTransferChannel) simulator.getModel().getInputChannel(setRecordChannelName);
		updateRecord = (DataTransferChannel) simulator.getModel().getChannel(updateRecordChannelName);
		simulator.addNativeReceiver(this, updateRecord);
	}
	
	
	@Override
	public void onReceiveFromModel(Event event, SystemState nextSystemState) {
		Expression message = event.getMessage();
		Constant newValue = (Constant)((Term) message).getChild(0);
		ResourcePath path = event.getInputResourcePath();
		ResourceIdentifier identifier = event.getResourceIdentifier(path);
//		String varName = identifier.getPathParams().get(0).toString().replace("\"","");
		ResourcePath parent = identifier.getParent();
		ResourceIdentifier parentIdent = event.getResourceIdentifier(parent);
		JsonTerm data =(JsonTerm) simulator.getCurState().getResource(parentIdent).getState().getValue();
		String key = data.get("key").toString().replace("\"", "");
		String tableName = data.get("table").toString();
		String dbName = data.get("dbName").toString();
		
		ResourcePath recordPath = setRecordChannel.getOutputResources().iterator().next();
		Resource recordResource = null;
		for(var res : nextSystemState.getRootResources()) {
			if(res.getResourceIdentifier().toString().equals("db")) {
				recordResource = res.getChildrenMap().get(dbName).getChildrenMap().get("tables").getChildrenMap().get(tableName);
				break;
			}
		}
		
		JsonTerm dbData = (JsonTerm) simulator.getCurState().getResource(recordResource.getParent().getParent().getResourceIdentifier()).getState().getValue();
		String dbUrl = dbData.get("url").toString().replace("\"", "");
		String dbUser = dbData.get("user").toString().replace("\"", "");
		String dbPass = dbData.get("password").toString().replace("\"", "");
		RecordSender sender = new RecordSender(simulator, setRecordChannel, recordPath, recordResource, dbUrl, dbUser, dbPass);
		
		switch(newValue.getType().getTypeName()) {
		case "Int":
			sender.updateRecord(tableName.replace("\"", ""), key, Integer.parseInt(newValue.toString()));
			break;
		case "Str":
			sender.updateRecord(tableName, key, newValue.toString());
			break;
		}
	}
	
	
	
}
