import assert from 'node:assert';
import AuditSource from '../auditsource.js';
import BoxError from '../boxerror.js';
import { HttpError } from '@cloudron/connect-lastmile';
import { HttpSuccess } from '@cloudron/connect-lastmile';
import network from '../network.js';
import safe from 'safetydance';


async function getBlocklist(req, res, next) {
    const [error, blocklist] = await safe(network.getBlocklist());
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, { blocklist }));
}

async function setBlocklist(req, res, next) {
    assert.strictEqual(typeof req.body, 'object');

    // this is a string to allow comments
    if (typeof req.body.blocklist !== 'string') return next(new HttpError(400, 'blocklist must be a string'));

    req.clearTimeout(); // can take a while if there is a lot of network ranges

    const [error] = await safe(network.setBlocklist(req.body.blocklist, AuditSource.fromRequest(req)));
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, {}));
}

async function getDynamicDns(req, res, next) {
    const [error, enabled] = await safe(network.getDynamicDns());
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, { enabled }));
}

async function setDynamicDns(req, res, next) {
    assert.strictEqual(typeof req.body, 'object');

    if (typeof req.body.enabled !== 'boolean') return next(new HttpError(400, 'enabled boolean is required'));

    const [error] = await safe(network.setDynamicDns(req.body.enabled));
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, {}));
}

async function getIPv4Config(req, res, next) {
    const [error, ipv4Config] = await safe(network.getIPv4Config());
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, ipv4Config));
}

async function setIPv4Config(req, res, next) {
    assert.strictEqual(typeof req.body, 'object');

    if (!req.body.provider || typeof req.body.provider !== 'string') return next(new HttpError(400, 'provider is required'));

    const [error] = await safe(network.setIPv4Config(req.body));
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, {}));
}

async function getIPv6Config(req, res, next) {
    const [error, ipv6Config] = await safe(network.getIPv6Config());
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, ipv6Config));
}

async function setIPv6Config(req, res, next) {
    assert.strictEqual(typeof req.body, 'object');

    if (!req.body.provider || typeof req.body.provider !== 'string') return next(new HttpError(400, 'provider is required'));

    const [error] = await safe(network.setIPv6Config(req.body));
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, {}));
}

async function getIPv4(req, res, next) {
    const [error, ip] = await safe(network.getIPv4());
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, { ip }));
}

async function getIPv6(req, res, next) {
    const [error, ip] = await safe(network.getIPv6()); // ignore any error
    if (error) return next(BoxError.toHttpError(error));

    next(new HttpSuccess(200, { ip }));
}

export default {
    getBlocklist,
    setBlocklist,

    getDynamicDns,
    setDynamicDns,

    getIPv4Config,
    setIPv4Config,

    getIPv6Config,
    setIPv6Config,

    getIPv4,
    getIPv6,
};
