// Path: src/main/java/com/apresa/restflow/AbstractBeanFlow.java
// public class AbstractBeanFlow<T> {
// 
// 	private StateMachine<T> fsm;
// 
// 	public AbstractBeanFlow() {
// 		fsm = new StateMachine<>(this);
// 	}
// 
// 	public boolean raise(Event event, T object) throws StateMachineException {
// 		return fsm.raise(event, object);
// 	}
// 
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/model/Transfer.java
// public class Transfer {
// 	@StateReference
// 	public TransferStatus status = TransferStatus.INITIAL;
// 
// 	public Float amount;
// 	public String src;
// 	public String target;
// 	public String otpHash;
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/support/Utils.java
// public class Utils {
// 
// 	public static String hashOTP(String otp) {
// 		return Integer.toString(otp.hashCode());
// 	}
// 
// 	public static boolean checkValidSignature(Transfer transfer,
// 			String signature) {
// 
// 		return signature.equals("SIGNATURE");
// 	}
// 
// 	public static void addOTP(Transfer transfer) {
// 		transfer.otpHash = hashOTP("OTP");
// 	}
// 
// 	public static boolean checkValidData(Transfer transfer) {
// 		return transfer.amount > 0 && transfer.src != null && transfer.target != null;
// 	}
// 
// }


import com.apresa.restflow.AbstractBeanFlow;
import com.apresa.restflow.annotations.*;
import com.apresa.restflow.samples.transfers.model.Transfer;
import com.apresa.restflow.samples.transfers.support.Utils;
public class TransferFlow extends AbstractBeanFlow<Transfer>{

	@Guard(TransferEvents.SIGN)
	private boolean checkValidSignature(Transfer transfer, @EventParam("signature") String signature) {
		return Utils.checkValidSignature(transfer, signature);
	}

	@Guard(TransferEvents.EXECUTE)
	private boolean checkValidOTP(Transfer transfer, @EventParam("otp") String otp) {
		return Utils.hashOTP(otp).equals(transfer.otpHash);
	}

	@OnState(TransferStatusConst.PENDING_OTP)
	private void generateOTP(Transfer transfer) {
		Utils.addOTP(transfer);
	}

	@On(TransferEvents.FILL)
	private void fillData(Transfer transfer, @EventParam("amount") Float amount, @EventParam("src") String src, @EventParam("target") String target) {
		transfer.amount = amount != null ? amount : transfer.amount;
		transfer.src = src != null ? src : transfer.src;
		transfer.target = target != null ? target : transfer.target;
	}

	@Guards({
		@Guard(TransferEvents.PROCEED),
		@Guard(TransferEvents.SIGN),
		@Guard(TransferEvents.EXECUTE)
	})

// Path: src/main/java/com/apresa/restflow/AbstractBeanFlow.java
// public class AbstractBeanFlow<T> {
// 
// 	private StateMachine<T> fsm;
// 
// 	public AbstractBeanFlow() {
// 		fsm = new StateMachine<>(this);
// 	}
// 
// 	public boolean raise(Event event, T object) throws StateMachineException {
// 		return fsm.raise(event, object);
// 	}
// 
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/model/Transfer.java
// public class Transfer {
// 	@StateReference
// 	public TransferStatus status = TransferStatus.INITIAL;
// 
// 	public Float amount;
// 	public String src;
// 	public String target;
// 	public String otpHash;
// }
// 
// Path: src/test/java/com/apresa/restflow/samples/transfers/support/Utils.java
// public class Utils {
// 
// 	public static String hashOTP(String otp) {
// 		return Integer.toString(otp.hashCode());
// 	}
// 
// 	public static boolean checkValidSignature(Transfer transfer,
// 			String signature) {
// 
// 		return signature.equals("SIGNATURE");
// 	}
// 
// 	public static void addOTP(Transfer transfer) {
// 		transfer.otpHash = hashOTP("OTP");
// 	}
// 
// 	public static boolean checkValidData(Transfer transfer) {
// 		return transfer.amount > 0 && transfer.src != null && transfer.target != null;
// 	}
// 
// }


// Path: src/test/java/com/apresa/restflow/samples/transfers/flow/TransferFlow.java
import com.apresa.restflow.AbstractBeanFlow;
import com.apresa.restflow.annotations.*;
import com.apresa.restflow.samples.transfers.model.Transfer;
import com.apresa.restflow.samples.transfers.support.Utils;

public class TransferFlow extends AbstractBeanFlow<Transfer>{

	@Guard(TransferEvents.SIGN)
	private boolean checkValidSignature(Transfer transfer, @EventParam("signature") String signature) {
		return Utils.checkValidSignature(transfer, signature);
	}

	@Guard(TransferEvents.EXECUTE)
	private boolean checkValidOTP(Transfer transfer, @EventParam("otp") String otp) {
		return Utils.hashOTP(otp).equals(transfer.otpHash);
	}

	@OnState(TransferStatusConst.PENDING_OTP)
	private void generateOTP(Transfer transfer) {
		Utils.addOTP(transfer);
	}

	@On(TransferEvents.FILL)
	private void fillData(Transfer transfer, @EventParam("amount") Float amount, @EventParam("src") String src, @EventParam("target") String target) {
		transfer.amount = amount != null ? amount : transfer.amount;
		transfer.src = src != null ? src : transfer.src;
		transfer.target = target != null ? target : transfer.target;
	}

	@Guards({
		@Guard(TransferEvents.PROCEED),
		@Guard(TransferEvents.SIGN),
		@Guard(TransferEvents.EXECUTE)
	})

	private boolean validateData(Transfer transfer) {