<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
    <changeSet id="1" author="pinfieldharm">
        <sql dbms="snowflake" endDelimiter=";;" splitStatements="true" stripComments="true">
        <![CDATA[
            CREATE OR REPLACE PROCEDURE DISTRIBUTION.<SCHEMA_NAME>.sp_store_backfill_cycle(store_backfill_id DOUBLE)
            RETURNS DOUBLE
            LANGUAGE javascript
            AS
            $$
                // Update status of outstanding deliveries orders. (SNOWFLAKE)
                snowflake.execute({
                    sqlText: `UPDATE store_backfill_release sbr
                    SET 
                        sbr.delivery_ended = eqd.delivery_ended,
                        sbr.final_status = eqd.status,
                        sbr.error_log = eqd.error_log
                    FROM
                        orchard_app_reporting_v2.reportsdd_direct_delivery.encoding_queue eq,
                        orchard_app_reporting_v2.reportsdd_direct_delivery.encoding_queue_detail eqd
                    WHERE
                        sbr.final_status is null
                        and sbr.encoding_order_id is not null
                        and sbr.encoding_order_id = eq.encoding_order_id
                        and eqd.encoding_queue_id = eq.encoding_queue_id
                        and eqd.upc = sbr.upc
                        and eqd.status not in ('new', 'ready_to_encode', 'encoding', 'ready_to_deliver', 'delivering', 'delivery_failure', 'cancelled', 'encoded', 'queued_for_delivery')
                        and sbr.store_backfill_id = :1;`,
                    binds: [STORE_BACKFILL_ID]
                  });

                // Compute next batch size
                var next_batch_size_rs = snowflake.execute({
                    sqlText:  `SELECT
                    LEAST(sb.batch_size_max, GREATEST(0, sb.in_flight_max - stats.in_flight)) next_batch_size
                  FROM 
                    store_backfill sb
                      INNER JOIN (
                    SELECT 
                        store_backfill_id,
                        count_if(encoding_order_id IS NOT NULL AND final_status IS NULL) in_flight,
                        count_if(encoding_order_id IS NULL) remaining
                    from store_backfill_release
                    where store_backfill_id = :1
                    group by store_backfill_id
                  ) stats on stats.store_backfill_id = sb.store_backfill_id
                  WHERE sb.store_backfill_id = :1;`,
                    binds: [STORE_BACKFILL_ID]
                  });
                var next_batch_size = 0;
                if (next_batch_size_rs.next()) {
                    next_batch_size = next_batch_size_rs.getColumnValue(1);
                };
                next_batch_size = next_batch_size_rs.getColumnValue(1);
                
                // Exit if there's nothing to queue up.
                if (next_batch_size == 0) {
                    return 0;
                }

                // Next batch number
                batch_number_rs = snowflake.execute({sqlText: 'select seq_store_backfill_batch_number.nextval from dual;'})
                batch_number_rs.next();
                var batch_number = batch_number_rs.getColumnValue(1);

                // Update items for next batch 
                snowflake.execute({
                    sqlText: `UPDATE store_backfill_release sb
                  SET sb.batch_number = :1
                  FROM (
                      SELECT store_backfill_release_id
                      FROM store_backfill_release
                      WHERE batch_number is null
                      AND store_backfill_id = :2
                      LIMIT ` + next_batch_size + `) q
                  WHERE sb.store_backfill_release_id = q.store_backfill_release_id;`,
                    binds: [batch_number, STORE_BACKFILL_ID]
                  });
                
                return batch_number;
            $$;;
        ]]>
        </sql>
        <rollback>
            <sql dbms="snowflake" endDelimiter=";;" splitStatements="true" stripComments="true">
            <![CDATA[
                DROP PROCEDURE IF EXISTS DISTRIBUTION.<SCHEMA_NAME>.sp_store_backfill_cycle(DOUBLE);;
            ]]>
            </sql>
        </rollback>
    </changeSet>
</databaseChangeLog>
