import apps from './apps.js';
import assert from 'node:assert';
import BoxError from './boxerror.js';
import constants from './constants.js';
import logger from './logger.js';
import eventlog from './eventlog.js';
import paths from './paths.js';
import safe from 'safetydance';
import settings from './settings.js';

const { log } = logger('branding');


async function getCloudronName() {
    const name = await settings.get(settings.CLOUDRON_NAME_KEY);
    return name || 'Cloudron';
}

async function setCloudronName(name, auditSource) {
    assert.strictEqual(typeof name, 'string');
    assert(auditSource && typeof auditSource === 'object');

    if (!name) throw new BoxError(BoxError.BAD_FIELD, 'name is empty');

    // some arbitrary restrictions (for sake of ui layout)
    // if this is changed, adjust dashboard/branding.html
    if (name.length > 64) throw new BoxError(BoxError.BAD_FIELD, 'name cannot exceed 64 characters');

    // mark apps using oidc addon to be reconfigured
    const [, installedApps] = await safe(apps.list());
    await safe(apps.configureApps(installedApps.filter((a) => !!a.manifest.addons?.oidc), { scheduleNow: true }, auditSource), { debug: log });

    await settings.set(settings.CLOUDRON_NAME_KEY, name);
    await eventlog.add(eventlog.ACTION_BRANDING_NAME, auditSource, { name });
}

async function getCloudronAvatar() {
    let avatar = await settings.getBlob(settings.CLOUDRON_AVATAR_KEY);
    if (avatar) return avatar;

    avatar = safe.fs.readFileSync(paths.CLOUDRON_DEFAULT_AVATAR_FILE);
    if (avatar) return avatar;

    throw new BoxError(BoxError.FS_ERROR, `Could not read avatar: ${safe.error.message}`);
}

async function setCloudronAvatar(avatar, auditSource) {
    assert(Buffer.isBuffer(avatar));
    assert(auditSource && typeof auditSource === 'object');

    await settings.setBlob(settings.CLOUDRON_AVATAR_KEY, avatar);
    await eventlog.add(eventlog.ACTION_BRANDING_AVATAR, auditSource, {});
}

async function getCloudronBackground() {
    const background = await settings.getBlob(settings.CLOUDRON_BACKGROUND_KEY);
    if (!background) return null;

    return background;
}

async function setCloudronBackground(background) {
    assert(background === null || Buffer.isBuffer(background));

    await settings.setBlob(settings.CLOUDRON_BACKGROUND_KEY, background);
}

async function getFooter() {
    const value = await settings.get(settings.FOOTER_KEY);
    return value || constants.FOOTER;
}

async function renderFooter() {
    const footer = await getFooter();
    const year = new Date().getFullYear();

    return footer.replace(/%YEAR%/g, year)
        .replace(/%VERSION%/g, constants.VERSION);
}

async function setFooter(footer, auditSource) {
    assert.strictEqual(typeof footer, 'string');
    assert(auditSource && typeof auditSource === 'object');

    await settings.set(settings.FOOTER_KEY, footer);
    await eventlog.add(eventlog.ACTION_BRANDING_FOOTER, auditSource, { footer });
}

export default {
    getCloudronName,
    setCloudronName,

    getCloudronAvatar,
    setCloudronAvatar,

    getCloudronBackground,
    setCloudronBackground,

    getFooter,
    setFooter,

    renderFooter
};
