"use strict";
Object.defineProperty(exports, "__esModule", {
    value: true
});
function _export(target, all) {
    for(var name in all)Object.defineProperty(target, name, {
        enumerable: true,
        get: Object.getOwnPropertyDescriptor(all, name).get
    });
}
_export(exports, {
    get down () {
        return down;
    },
    get up () {
        return up;
    }
});
const NOTES_BATCH_SIZE = 10000;
const NOTES_DERIVED_SIDE_EFFECT_TRIGGERS = [
    'notify_notes_changed',
    'record_notes_changelog',
    'fhir_refresh'
];
const NOTE_TYPE_REFERENCE_DATA = [
    {
        id: 'notetype-treatmentPlan',
        code: 'treatmentPlan'
    },
    {
        id: 'notetype-discharge',
        code: 'discharge'
    },
    {
        id: 'notetype-clinicalMobile',
        code: 'clinicalMobile'
    },
    {
        id: 'notetype-handover',
        code: 'handover'
    },
    {
        id: 'notetype-areaToBeImaged',
        code: 'areaToBeImaged'
    },
    {
        id: 'notetype-resultDescription',
        code: 'resultDescription'
    },
    {
        id: 'notetype-other',
        code: 'other'
    },
    {
        id: 'notetype-system',
        code: 'system'
    },
    {
        id: 'notetype-admission',
        code: 'admission'
    },
    {
        id: 'notetype-medical',
        code: 'medical'
    },
    {
        id: 'notetype-surgical',
        code: 'surgical'
    },
    {
        id: 'notetype-nursing',
        code: 'nursing'
    },
    {
        id: 'notetype-dietary',
        code: 'dietary'
    },
    {
        id: 'notetype-pharmacy',
        code: 'pharmacy'
    },
    {
        id: 'notetype-physiotherapy',
        code: 'physiotherapy'
    },
    {
        id: 'notetype-social',
        code: 'social'
    }
];
const noteTypeIds = NOTE_TYPE_REFERENCE_DATA.map(({ id })=>`'${id}'`).join(', ');
const noteTypeCodes = NOTE_TYPE_REFERENCE_DATA.map(({ code })=>`'${code}'`).join(', ');
async function columnExists(query, columnName) {
    const [results] = await query.sequelize.query(`
    SELECT EXISTS (
      SELECT 1
      FROM information_schema.columns
      WHERE table_schema = 'public'
      AND table_name = 'notes'
      AND column_name = :columnName
    ) AS exists
  `, {
        replacements: {
            columnName
        }
    });
    return Boolean(results[0]?.exists);
}
async function triggerExists(query, triggerName) {
    const [results] = await query.sequelize.query(`
    SELECT EXISTS (
      SELECT 1
      FROM information_schema.triggers
      WHERE event_object_schema = 'public'
      AND event_object_table = 'notes'
      AND trigger_name = :triggerName
    ) AS exists
  `, {
        replacements: {
            triggerName
        }
    });
    return Boolean(results[0]?.exists);
}
async function setKnownDerivedSideEffectTriggersEnabled(query, enabled) {
    for (const triggerName of NOTES_DERIVED_SIDE_EFFECT_TRIGGERS){
        if (await triggerExists(query, triggerName)) {
            await query.sequelize.query(`ALTER TABLE notes ${enabled ? 'ENABLE' : 'DISABLE'} TRIGGER ${triggerName}`);
        }
    }
}
async function updateNotesInBatches(query, filter, caseExpression, fallbackValue) {
    let lastId = null;
    do {
        const queryResults = await query.sequelize.query(`
      WITH batch AS (
        SELECT id
        FROM notes
        WHERE ${lastId ? 'id > :lastId AND' : ''} ${filter}
        ORDER BY id
        LIMIT ${NOTES_BATCH_SIZE}
      ),
      updated AS (
        UPDATE notes
        SET note_type = CASE note_type
            ${caseExpression}
            ELSE '${fallbackValue}'
        END
        FROM batch
        WHERE notes.id = batch.id
        RETURNING notes.id
      )
      SELECT id::text AS max_id
      FROM batch
      ORDER BY id DESC
      LIMIT 1
    `, {
            replacements: {
                lastId
            }
        });
        const results = queryResults[0];
        lastId = results[0]?.max_id ?? null;
    }while (lastId)
}
async function up(query) {
    if (!await columnExists(query, 'note_type') || await columnExists(query, 'note_type_id')) {
        return;
    }
    const otherNoteType = NOTE_TYPE_REFERENCE_DATA.find(({ code })=>code === 'other');
    const upCaseExpression = NOTE_TYPE_REFERENCE_DATA.map(({ id, code })=>`WHEN '${code}' THEN '${id}'`).join('\n        ');
    try {
        await setKnownDerivedSideEffectTriggersEnabled(query, false);
        await updateNotesInBatches(query, `note_type NOT IN (${noteTypeIds})`, upCaseExpression, otherNoteType.id);
        // Refresh planner stats on note_type after rewriting every value.
        await query.sequelize.query(`ANALYZE notes`);
    } finally{
        await setKnownDerivedSideEffectTriggersEnabled(query, true);
    }
}
async function down(query) {
    if (!await columnExists(query, 'note_type')) {
        return;
    }
    const otherNoteType = NOTE_TYPE_REFERENCE_DATA.find(({ code })=>code === 'other');
    const downCaseExpression = NOTE_TYPE_REFERENCE_DATA.map(({ id, code })=>`WHEN '${id}' THEN '${code}'`).join('\n        ');
    try {
        await setKnownDerivedSideEffectTriggersEnabled(query, false);
        await updateNotesInBatches(query, `note_type NOT IN (${noteTypeCodes})`, downCaseExpression, otherNoteType.code);
        await query.sequelize.query(`ANALYZE notes`);
    } finally{
        await setKnownDerivedSideEffectTriggersEnabled(query, true);
    }
}

//# sourceMappingURL=1759894448777-backfillNoteTypeIds.js.map