"use strict";

const dateUtils = require('./date_utils');
const optionService = require('./options');
const fs = require('fs-extra');
const dataDir = require('./data_dir');
const log = require('./log');
const sqlInit = require('./sql_init');
const syncMutexService = require('./sync_mutex');
const cls = require('./cls');

async function regularBackup() {
    const now = new Date();
    const lastBackupDate = dateUtils.parseDateTime(await optionService.getOption('lastBackupDate'));

    console.log(lastBackupDate);

    if (now.getTime() - lastBackupDate.getTime() > 43200 * 1000) {
        await backupNow();
    }

    await cleanupOldBackups();
}

async function backupNow() {
    // we don't want to backup DB in the middle of sync with potentially inconsistent DB state

    await syncMutexService.doExclusively(async () => {
        const backupFile = dataDir.BACKUP_DIR + "/" + "backup-" + dateUtils.getDateTimeForFile() + ".db";

        fs.copySync(dataDir.DOCUMENT_PATH, backupFile);

        log.info("Created backup at " + backupFile);

        await optionService.setOption('lastBackupDate', dateUtils.nowDate());
    });
}

async function cleanupOldBackups() {
    const now = new Date();

    fs.readdirSync(dataDir.BACKUP_DIR).forEach(file => {
        const match = file.match(/backup-([0-9 -:]+)\.db/);

        if (match) {
            const date_str = match[1];

            const date = Date.parse(date_str);

            if (now.getTime() - date.getTime() > 30 * 24 * 3600 * 1000) {
                log.info("Removing old backup - " + file);

                fs.unlink(dataDir.BACKUP_DIR + "/" + file);
            }
        }
    });
}

if (!fs.existsSync(dataDir.BACKUP_DIR)) {
    fs.mkdirSync(dataDir.BACKUP_DIR, 0o700);
}

sqlInit.dbReady.then(() => {
    setInterval(cls.wrap(regularBackup), 60 * 60 * 1000);

    // kickoff backup immediately
    setTimeout(cls.wrap(regularBackup), 1000);
});

module.exports = {
    backupNow
};