import ballerina/io;
import ballerina/runtime;
import ballerina/http;
import ballerina/log;
import wso2/gateway;

stream<gateway:IntermediateStream> s{{name}}intermediateStream = new;
stream<gateway:GlobalThrottleStreamDTO> s{{name}}resultStream = new;
stream<gateway:EligibilityStreamDTO> s{{name}}eligibilityStream = new;
stream<gateway:RequestStreamDTO> s{{name}}reqCopy= gateway:requestStream;
stream<gateway:GlobalThrottleStreamDTO> s{{name}}globalThrotCopy = gateway:globalThrottleStream;

function {{funcName}}() {

    forever {
        from s{{name}}reqCopy
        select s{{name}}reqCopy.messageID as messageID, (s{{name}}reqCopy.{{tierType}} == "{{name}}") as
        isEligible, s{{name}}reqCopy.{{policyKey}} as throttleKey, 0 as expiryTimestamp
        => (gateway:EligibilityStreamDTO[] counts) {
        foreach var c in counts{
            s{{name}}eligibilityStream.publish(c);
        }
        }

        from s{{name}}eligibilityStream
        throttler:timeBatch({{unitTime}})
        where s{{name}}eligibilityStream.isEligible == true
        select s{{name}}eligibilityStream.throttleKey as throttleKey, count() as eventCount, {{stopOnQuotaReach}} as
        stopOnQuota, expiryTimeStamp
        group by s{{name}}eligibilityStream.throttleKey
        => (gateway:IntermediateStream[] counts) {
        foreach var c in counts{
            s{{name}}intermediateStream.publish(c);
        }
        }

        from s{{name}}intermediateStream
        select s{{name}}intermediateStream.throttleKey, s{{name}}intermediateStream.eventCount>= {{count}} as isThrottled,
        s{{name}}intermediateStream.stopOnQuota, s{{name}}intermediateStream.expiryTimeStamp
        group by s{{name}}eligibilityStream.throttleKey
        => (gateway:GlobalThrottleStreamDTO[] counts) {
        foreach var c in counts{
            s{{name}}resultStream.publish(c);
        }
        }

        from s{{name}}resultStream
        throttler:emitOnStateChange(s{{name}}resultStream.throttleKey, s{{name}}resultStream.isThrottled)
        select s{{name}}resultStream.throttleKey as throttleKey, s{{name}}resultStream.isThrottled,
        s{{name}}resultStream.stopOnQuota, s{{name}}resultStream.expiryTimeStamp
        => (gateway:GlobalThrottleStreamDTO[] counts) {
        foreach var c in counts{
            s{{name}}globalThrotCopy.publish(c);
        }
        }
    }
}

