'use strict';

const crypto = require('node:crypto'),
    fs = require('node:fs'),
    path = require('node:path'),
    paths = require('../src/paths.js').default,
    safe = require('safetydance');

exports.up = async function(db) {
    const backups = await db.runSql('SELECT format, COUNT(*) AS count FROM backups GROUP BY format WITH ROLLUP', []); // https://dev.mysql.com/doc/refman/8.4/en/group-by-modifiers.html

    let tgzCount = 0, rsyncCount = 0, totalCount = 0;
    for (const r of backups) {
        if (r.format === 'tgz') tgzCount = r.count;
        else if (r.format === 'rsync') rsyncCount = r.count;
        else if (r.format === null) totalCount = r.count; // ROLLUP gives count by group and also an accumulated "null"
    }
    let theOneFormat = null;
    if (tgzCount === totalCount) theOneFormat = 'tgz';
    else if (rsyncCount === totalCount) theOneFormat = 'rsync';
    console.log(`Backup counts. rsync: ${rsyncCount} tgz: ${tgzCount} total: ${totalCount} . theOneFormat: ${theOneFormat}`);

    const backupSites = await db.runSql('SELECT * FROM backupSites');
    const currentBackupSite = backupSites.length ? backupSites[0] : null;
    let cloneBackupSite = null;
    if (totalCount && currentBackupSite.format !== theOneFormat) {
        const cloneId = crypto.randomUUID();
        cloneBackupSite = Object.assign({}, backupSites[0], { id: cloneId });
        cloneBackupSite.format = currentBackupSite.format === 'rsync' ? 'tgz' : 'rsync';
        cloneBackupSite.name = 'Copy of Default';
        cloneBackupSite.schedule = 'never';
        cloneBackupSite._managedMountPath = path.join(paths.MANAGED_BACKUP_MOUNT_DIR, cloneId); // this won't work until the user remounts
        cloneBackupSite.enableForUpdates = false;
        console.log(`Existing format is ${currentBackupSite.format} . Adding clone backup site for ${cloneBackupSite.format}`);

        await db.runSql('INSERT INTO backupSites (id, name, provider, configJson, limitsJson, integrityKeyPairJson, retentionJson, schedule, encryptionJson, format, enableForUpdates) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
            [ cloneBackupSite.id, cloneBackupSite.name, cloneBackupSite.provider, cloneBackupSite.configJson, cloneBackupSite.limitsJson, cloneBackupSite.integrityKeyPairJson, cloneBackupSite.retentionJson, cloneBackupSite.schedule,
              cloneBackupSite.encryptionJson, cloneBackupSite.format, cloneBackupSite.enableForUpdates ]);

        const cloneInfoDir = path.join(paths.BACKUP_INFO_DIR, cloneId);
        fs.mkdirSync(cloneInfoDir, { recursive: true }); // this gets chown'ed by start.sh
    }

    await db.runSql('ALTER TABLE backups ADD siteId VARCHAR(128)');
    if (totalCount) {
        const ext = safe.JSON.parse(currentBackupSite.encryptionJson) ? '.tar.gz.enc' : '.tar.gz'; // assume user had encryption in the past too
        console.log(`Adjusting remotePath of existing tgz backups with ${ext}`);
        await db.runSql('UPDATE backups SET remotePath=CONCAT(remotePath, ?) WHERE format=?', [ ext, 'tgz' ]);
        await db.runSql('UPDATE backups SET siteId=? WHERE format=?', [ currentBackupSite.id, currentBackupSite.format ]);
        if (cloneBackupSite) await db.runSql('UPDATE backups SET siteId=? WHERE format=?', [ cloneBackupSite.id, cloneBackupSite.format ]);
    }
    await db.runSql('ALTER TABLE backups MODIFY siteId VARCHAR(128) NOT NULL');
    await db.runSql('ALTER TABLE backups ADD FOREIGN KEY(siteId) REFERENCES backupSites(id)');
    await db.runSql('ALTER TABLE backups DROP COLUMN format');
};

exports.down = async function(/*db*/) {
};
