/* Enter a unique ExecutionPlan */
@Plan:name('$executionPlanName')

/* Enter a unique description for ExecutionPlan */
-- @Plan:description('ExecutionPlan')

/* define streams/tables and write queries here ... */

@Import('org.wso2.geo.StandardSpatialEvents:1.0.0')
define stream dataIn (id string, owner string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string);

@Export('iot.per.device.stream.geo.FusedSpatialEvent:1.0.0')
define stream dataOut (id string, owner string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, state string, information string, notify bool );

@Export('iot.per.device.stream.geo.AlertNotifications:1.0.0')
define stream alertsOut (id string, owner string, state string, information string, timeStamp long, latitude double, longitude double, type string);

/* Check if the device is within the geo fence. */
from dataIn[id == "$deviceId" and owner == "$owner"]
select id, owner, latitude, longitude, timeStamp, type, speed, heading, eventId, geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin
insert into withinStream;

from withinStream[isWithin == true]
select id, owner, latitude, longitude,timeStamp, type, speed, heading, "ALERTED" as state, str:concat("The ", type, " device `", id, "` of $owner is inside $areaName area!") as information, true as notify
insert into dataOut;

from withinStream[isWithin == false]
select id, owner, latitude, longitude,timeStamp, type, speed, heading, "NORMAL" as state, "" as information, false as notify
insert into dataOut;

from every fs1=withinStream, fs2=withinStream[fs1.isWithin != isWithin]
select fs2.id, fs2.owner, fs2.latitude, fs2.longitude, fs2.timeStamp, fs2.type, fs2.speed, fs2.heading, fs2.eventId, fs2.isWithin
insert into crossedStream;

from crossedStream[isWithin == true]
select id, owner, "ALERTED" as state, str:concat("The ", type, " device `", id, "` of $owner is inside $areaName area!") as information, timeStamp, latitude, longitude, type
insert into alertsOut;
