"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.start = void 0;
const promises_1 = __importDefault(require("fs/promises"));
const execa_1 = __importDefault(require("execa"));
const executable_1 = require("./executable");
const ip_1 = require("./ip");
async function start({ client = {}, configuration = '/tmp/wireguard.conf', server = {}, } = {}) {
    if (!client.port)
        client.port = 25344;
    if (!client.privateKey)
        client.privateKey = process.env.WIREGUARD_CLIENT_PRIVATE_KEY;
    if (!server.host)
        server.host = process.env.WIREGUARD_SERVER_HOST;
    if (!server.port)
        server.port = 4343;
    if (!server.publicKey)
        server.publicKey = process.env.WIREGUARD_SERVER_PUBLIC_KEY;
    guardAgainstInvalidClientOptions(client);
    guardAgainstInvalidServerOptions(server);
    await promises_1.default.writeFile(configuration, [
        '[Interface]',
        `PrivateKey = ${client.privateKey}`,
        `ListenPort = ${server.port}`,
        `Address = ${(0, ip_1.generateRandomAddressInCIDR)('10.8.0.0/16')}/32`,
        '',
        '[Peer]',
        `PublicKey = ${server.publicKey}`,
        'AllowedIPs = 0.0.0.0/0',
        `Endpoint = ${server.host}:${server.port}`,
        '',
        '[Socks5]',
        `BindAddress = 127.0.0.1:${client.port}`,
    ].join('\n'));
    const wireproxy = `${(0, executable_1.getExecutableDirectory)()}/wireproxy`;
    /**
     * This gives full permissions to the owner as well as
     * read and execute to other users and groups.
     *
     * Equivalent of `chmod 755` in octal representation.
     */
    await promises_1.default.chmod(wireproxy, 0o755).catch(() => 
    // eslint-disable-next-line no-console
    console.log('Unable to chmod the wireproxy binary, proceeding anyway'));
    const daemon = (0, execa_1.default)(wireproxy, [`--config=${configuration}`, '--daemon']);
    daemon.stdout?.pipe(process.stdout);
    daemon.stderr?.pipe(process.stderr);
    return daemon.then(() => `socks5://localhost:${client.port}`);
}
exports.start = start;
function guardAgainstInvalidClientOptions(client) {
    if (!client.privateKey) {
        throw new Error(`No client private key was provided, either provide one explicitly or set the WIREGUARD_CLIENT_PRIVATE_KEY environment variable`);
    }
}
function guardAgainstInvalidServerOptions(server) {
    if (!server.host) {
        throw new Error(`No server host was provided, either provide one explicitly or set the WIREGUARD_SERVER_HOST environment variable`);
    }
    if (!server.publicKey) {
        throw new Error(`No server public key was provided, either provide one explicitly or set the WIREGUARD_SERVER_PUBLIC_KEY environment variable`);
    }
}
