/* eslint-disable @typescript-eslint/naming-convention */
import { execSync } from 'child_process';
import http from 'http';
import open from 'open';
import url from 'url';
import yargs, { Arguments } from 'yargs';
import { hideBin } from 'yargs/helpers';

const argv = yargs(hideBin(process.argv)).argv as Arguments<{ registry?: string }>;

const registry = (argv.registry ?? execSync('npm config get registry').toString())
    .trim()
    .replace(/\/?$/, '/');

if (registry.includes('registry.npmjs.org')) {
    throw new Error('This is incompatible with the default npm repository.');
}

open(registry + 'oauth/authorize');

http.createServer((req, res) => {
    if (!req.url) {
        throw new Error('Request URL is not defined!');
    }

    const {
        query: { username, jwt_token, npm_token, redirect_uri },
    } = url.parse(req.url, true);

    if (typeof username !== 'string') {
        throw new Error('"username" should be a string value!');
    }

    if (typeof jwt_token !== 'string') {
        throw new Error('"jwt_token" should be a string value!');
    }

    if (typeof npm_token !== 'string') {
        throw new Error('"npm_token" should be a string value!');
    }

    if (typeof redirect_uri !== 'string') {
        throw new Error('"redirect_uri" should be a string value!');
    }

    const { host, pathname } = new URL(registry);

    execSync(`npm config set --no-workspaces //${host}${pathname}:_authToken "${npm_token}"`);

    res.writeHead(302, {
        Location: `${redirect_uri}?${new URLSearchParams({
            username,
            token: jwt_token,
        }).toString()}`,
    });
    res.end(() => {
        process.exit(0);
    });
}).listen(8239);
