import { Execution } from '../engine/Execution';
import { Token, TOKEN_TYPE } from '../engine/Token';
import { IBehaviour, Behaviour} from "./behaviours";
import { NODE_ACTION, FLOW_ACTION, EXECUTION_EVENT, TOKEN_STATUS, ITEM_STATUS, IFlow, ScriptHandler } from '../';
import { Item } from '../engine/Item';
import { Node, Element } from '.';
import { IExecution } from '../interfaces';
class Flow extends Element implements IFlow {
from: Node;
to: Node;
def;
isMessageFlow = false;
constructor(id, type, from, to, def) {
super();
this.id = id;
this.type = type;
this.from = from;
this.to = to;
this.def = def;
this.name = def.name;
this.isFlow = true;
}
describe() {
if (this.def.conditionExpression) {
// conditionExpression:{"$type":"bpmn:Expression","body":"true"}
let expression = this.def.conditionExpression.body;
return [['condition: ' , expression]];
}
else
return [];
}
/**
* ```xml
* if flow has a condition, it must be evaluated and if result is true flow will continue
* otherwise, flow will be discarded.
*
* ```
* @param item
*/
async run(item: Item) {
item.token.log('Flow(' + this.name +'|'+ this.id + ').run: from='+this.from.name+' to=' + this.to.name + " find action... " );
let action = FLOW_ACTION.take;
let result = await this.evaluateCondition(item);
if (result !== true) {
action = FLOW_ACTION.discard;
item.token.execution.doItemEvent(item, EXECUTION_EVENT.flow_discard,{flow:this.id});
}
else
{
item.token.execution.doItemEvent(item, EXECUTION_EVENT.flow_take,{flow:this.id});
item.token.info(`{"seq":${item.seq},"type":'${this.type}',"id":'${this.id}',"action":'Taken'}`);
item.token.log('(Flow:'+this.id+')Flow(' + this.name +'|'+ this.id + ').run: going to ' + this.to.id + " action : " + action);
}
return action;
}
async end(item) {
}
async evaluateCondition(item) {
// conditionExpression:{"$type":"bpmn:Expression","body":"true"}
if (this.def.conditionExpression) {
//console.log('flow definition ',this.def);
let expression = this.def.conditionExpression.body;
item.token.log('..conditionExpression:' + JSON.stringify(expression));
item.token.log(JSON.stringify(item.token.data));
let result = await item.context.scriptHandler.evaluateExpression(item, expression);
item.token.log('..conditionExpression:' + expression + " result: " + result);
return result;
}
return true;
}
async execute(item) {
}
}
// ---------------------------------------------
/**
* ```xml
* MessageFlow: can only be sent to active node in waiting
* or to a start event
*
* ```
* */
class MessageFlow extends Flow {
isMessageFlow = true;
async execute(item: Item) {
item.token.log('..MessageFlow -' + this.id + ' going to ' + this.to.id);
const execution:IExecution = item.token.execution;
let token = null;
execution.tokens.forEach(t => {
if (t.currentNode && t.currentNode.id == this.to.id)
token = t;
});
if (token) {
item.token.log(' signalling token:' + token.id );
execution.promises.push(token.signal(null));
}
else {
item.token.log(' signalling new token:');
execution.promises.push(Token.startNewToken(TOKEN_TYPE.Primary,execution, this.to, null, null, null, null));
}
}
}
export { Flow , MessageFlow}