/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

import fs from 'node:fs';
import { parse } from 'node:url';
import createDebug from 'debug';
import _ from 'lodash';
import RunCommand from './run.ts';

const _debug = createDebug('commands:quick');

import { Args, Command, Flags } from '@oclif/core';

class QuickCommand extends Command {
  // Untyped JS class - properties assigned dynamically
  [key: string]: any;

  async run() {
    const { flags, args } = await this.parse(QuickCommand);
    const url = args.target;

    const script: any = {
      config: {
        target: '',
        phases: [],
        mode: 'uniform',
        __createdByQuickCommand: true
      },
      scenarios: [
        {
          flow: []
        }
      ]
    };

    const p = parse(url);
    const target = `${p.protocol}//${p.host}`;
    script.config.target = target;

    // NOTE: pre-existing behavior: a target with no protocol crashes here.
    if (flags.insecure && (p.protocol as string).match(/https/)) {
      script.config.tls = {
        rejectUnauthorized: false
      };
    }

    script.config.phases.push({
      duration: 1,
      arrivalCount: flags.count
    });

    let requestSpec: any = {};
    if ((p.protocol as string).match('http')) {
      requestSpec.get = { url: url };
    } else if ((p.protocol as string).match('ws')) {
      requestSpec.send = 'hello from Artillery!';
    } else {
      console.error('Unknown protocol in target:', args.target);
      console.error('Supported protocols: HTTP(S) and WS(S)');
      process.exit(1);
    }

    if (flags.num > 1) {
      requestSpec = {
        loop: [requestSpec],
        count: flags.num
      };
    }

    script.scenarios[0].flow.push(requestSpec);
    if ((p.protocol as string).match(/ws/)) {
      script.scenarios[0].engine = 'ws';
    }

    const temporaryFile = (await import('tempy')).temporaryFile;
    const tmpf = temporaryFile({ extension: 'yml' });
    fs.writeFileSync(tmpf, JSON.stringify(script, null, 2), { flag: 'w' });

    const runArgs: string[] = [];
    if (flags.output) {
      runArgs.push('--output');
      runArgs.push(flags.output);
    }
    if (flags.quiet) {
      runArgs.push('--quiet');
    }

    runArgs.push(tmpf);

    RunCommand.run(runArgs);
  }
}

QuickCommand.description = 'run a simple test without writing a test script';
QuickCommand.flags = {
  count: Flags.string({
    char: 'c',
    description: 'Number of VUs to create',
    parse: (input: string) => parseInt(input, 10),
    default: 10
  } as any),
  num: Flags.string({
    char: 'n',
    description: 'Number of requests/messages that each VU will send',
    parse: (input: string) => parseInt(input, 10),
    default: 10
  } as any),
  output: Flags.string({
    char: 'o',
    description: 'Filename of the JSON report'
  }),
  insecure: Flags.boolean({
    char: 'k',
    description: 'Allow insecure TLS connections'
  }),
  quiet: Flags.boolean({
    char: 'q',
    description: 'Quiet mode'
  })
};
QuickCommand.args = {
  target: Args.string()
};

export default QuickCommand;
