import { Args, Command, Flags } from '@oclif/core';
import { CommonRunFlags } from '../cli/common-flags.ts';
import { parseResourceTags } from '../platform/aws/resource-tags.ts';

import RunCommand from './run.ts';

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

  static aliases = ['run:lambda'];
  static strict = false;

  async run() {
    const { flags, argv, args } = await this.parse(RunLambdaCommand);

    flags['platform-opt'] = [
      `region=${flags.region}`,
      `memory-size=${flags['memory-size']}`,
      `architecture=${flags.architecture}`
    ];

    delete flags.region;
    delete flags['memory-size'];
    delete flags.architecture;

    if (flags['lambda-role-arn']) {
      flags['platform-opt'].push(`lambda-role-arn=${flags['lambda-role-arn']}`);
    }

    if (flags['security-group-ids']) {
      flags['platform-opt'].push(
        `security-group-ids=${flags['security-group-ids']}`
      );
    }

    if (flags['subnet-ids']) {
      flags['platform-opt'].push(`subnet-ids=${flags['subnet-ids']}`);
    }

    flags.platform = 'aws:lambda';

    // NOTE: --aws-tags is passed through as-is via flags (cliArgs),
    // not via platform-opt. platform-opt values are split on "=" which
    // would truncate tag values containing "=".
    // Validate early, before any AWS resources are touched:
    try {
      parseResourceTags(flags['aws-tags']);
    } catch (err) {
      console.error((err as Error).message);
      process.exit(1);
    }

    RunCommand.runCommandImplementation(flags, argv, args);
  }
}

RunLambdaCommand.description = `launch a test using AWS Lambda
Launch a test on AWS Lambda

Examples:

  To run a test script in my-test.yml on AWS Lambda in us-east-1 region
  distributed across 10 Lambda functions:

    $ artillery run:lambda --region us-east-1 --count 10 my-test.yml
`;
RunLambdaCommand.flags = {
  ...CommonRunFlags,
  payload: Flags.string({
    char: 'p',
    description: 'Specify a CSV file for dynamic data'
  }),
  count: Flags.string({
    // locally defaults to number of CPUs with mode = distribute
    default: '1'
  }),
  architecture: Flags.string({
    description: 'Architecture of the Lambda function',
    default: 'arm64',
    options: ['arm64', 'x86_64']
  }),
  'memory-size': Flags.string({
    description: 'Memory size of the Lambda function',
    default: '4096'
  }),
  region: Flags.string({
    description: 'AWS region to run the test in',
    default: 'us-east-1'
  }),
  'lambda-role-arn': Flags.string({
    description: 'ARN of the IAM role to use for the Lambda function'
  }),
  'security-group-ids': Flags.string({
    description:
      'Comma-separated list of security group IDs to use for the Lambda function'
  }),
  'subnet-ids': Flags.string({
    description:
      'Comma-separated list of subnet IDs to use for the Lambda function'
  }),
  'aws-tags': Flags.string({
    description:
      'Comma-separated list of tags in key:value format to apply to AWS resources created for the test run (Lambda function and SQS queue), for example: --aws-tags "team:perf,cost-center:1234"'
  })
};

RunLambdaCommand.args = {
  script: Args.string({
    name: 'script',
    required: true
  })
};

export default RunLambdaCommand;
