/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */

import assert from 'node:assert';
import {describe, it} from 'node:test';

import {parseArguments} from '../src/bin/chrome-devtools-mcp-cli-options.js';

describe('cli args parsing', () => {
  const defaultArgs = {
    'category-emulation': true,
    categoryEmulation: true,
    'category-performance': true,
    categoryPerformance: true,
    'category-network': true,
    categoryNetwork: true,
    'category-extensions': false,
    categoryExtensions: false,
    'category-experimental-third-party': false,
    categoryExperimentalThirdParty: false,
    'auto-connect': undefined,
    autoConnect: undefined,
    'performance-crux': true,
    performanceCrux: true,
    'usage-statistics': true,
    usageStatistics: true,
    'redact-network-headers': false,
    redactNetworkHeaders: false,
    'allow-unrestricted-paths': false,
    allowUnrestrictedPaths: false,
  };

  it('parses with default args', async () => {
    const args = parseArguments('1.0.0', ['node', 'main.js'], {});
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      channel: 'stable',
    });
  });

  it('parses with browser url', async () => {
    const args = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--browserUrl', 'http://localhost:3000'],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      'browser-url': 'http://localhost:3000',
      browserUrl: 'http://localhost:3000',
      u: 'http://localhost:3000',
    });
  });

  it('parses with user data dir', async () => {
    const args = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--user-data-dir', '/tmp/chrome-profile'],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      channel: 'stable',
      'user-data-dir': '/tmp/chrome-profile',
      userDataDir: '/tmp/chrome-profile',
    });
  });

  it('parses an empty browser url', async () => {
    const args = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--browserUrl', ''],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      'browser-url': undefined,
      browserUrl: undefined,
      u: undefined,
      channel: 'stable',
    });
  });

  it('parses with executable path', async () => {
    const args = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--executablePath', '/tmp/test 123/chrome'],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      'executable-path': '/tmp/test 123/chrome',
      e: '/tmp/test 123/chrome',
      executablePath: '/tmp/test 123/chrome',
    });
  });

  it('parses viewport', async () => {
    const args = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--viewport', '888x777'],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      channel: 'stable',
      viewport: {
        width: 888,
        height: 777,
      },
    });
  });

  it('parses chrome args', async () => {
    const args = parseArguments(
      '1.0.0',
      [
        'node',
        'main.js',
        `--chrome-arg='--no-sandbox'`,
        `--chrome-arg='--disable-setuid-sandbox'`,
      ],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      channel: 'stable',
      'chrome-arg': ['--no-sandbox', '--disable-setuid-sandbox'],
      chromeArg: ['--no-sandbox', '--disable-setuid-sandbox'],
    });
  });

  it('parses ignore chrome args', async () => {
    const args = parseArguments(
      '1.0.0',
      [
        'node',
        'main.js',
        `--ignore-default-chrome-arg='--disable-extensions'`,
        `--ignore-default-chrome-arg='--disable-cancel-all-touches'`,
      ],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      channel: 'stable',
      'ignore-default-chrome-arg': [
        '--disable-extensions',
        '--disable-cancel-all-touches',
      ],
      ignoreDefaultChromeArg: [
        '--disable-extensions',
        '--disable-cancel-all-touches',
      ],
    });
  });

  it('parses wsEndpoint with ws:// protocol', async () => {
    const args = parseArguments(
      '1.0.0',
      [
        'node',
        'main.js',
        '--wsEndpoint',
        'ws://127.0.0.1:9222/devtools/browser/abc123',
      ],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      'ws-endpoint': 'ws://127.0.0.1:9222/devtools/browser/abc123',
      wsEndpoint: 'ws://127.0.0.1:9222/devtools/browser/abc123',
      w: 'ws://127.0.0.1:9222/devtools/browser/abc123',
    });
  });

  it('parses wsEndpoint with wss:// protocol', async () => {
    const args = parseArguments(
      '1.0.0',
      [
        'node',
        'main.js',
        '--wsEndpoint',
        'wss://example.com:9222/devtools/browser/abc123',
      ],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      'ws-endpoint': 'wss://example.com:9222/devtools/browser/abc123',
      wsEndpoint: 'wss://example.com:9222/devtools/browser/abc123',
      w: 'wss://example.com:9222/devtools/browser/abc123',
    });
  });

  it('parses wsHeaders with valid JSON', async () => {
    const args = parseArguments(
      '1.0.0',
      [
        'node',
        'main.js',
        '--wsEndpoint',
        'ws://127.0.0.1:9222/devtools/browser/abc123',
        '--wsHeaders',
        '{"Authorization":"Bearer token","X-Custom":"value"}',
      ],
      {},
    );
    assert.deepStrictEqual(args.wsHeaders, {
      Authorization: 'Bearer token',
      'X-Custom': 'value',
    });
  });

  it('parses disabled category', async () => {
    const args = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--no-category-emulation'],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      channel: 'stable',
      'category-emulation': false,
      categoryEmulation: false,
    });
  });
  it('parses auto-connect', async () => {
    const args = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--auto-connect'],
      {},
    );
    assert.deepStrictEqual(args, {
      ...defaultArgs,
      _: [],
      headless: false,
      $0: 'npx chrome-devtools-mcp@latest',
      channel: 'stable',
      'auto-connect': true,
      autoConnect: true,
    });
  });

  it('parses usage statistics flag', async () => {
    // Test default (should be true).
    const defaultArgs = parseArguments('1.0.0', ['node', 'main.js'], {});
    assert.strictEqual(defaultArgs.usageStatistics, true);

    // Test enabling it
    const enabledArgs = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--usage-statistics'],
      {},
    );
    assert.strictEqual(enabledArgs.usageStatistics, true);

    // Test disabling it
    const disabledArgs = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--no-usage-statistics'],
      {},
    );
    assert.strictEqual(disabledArgs.usageStatistics, false);
  });

  it('respects env variable', async () => {
    // Test default (should be true).
    const defaultArgs = parseArguments('1.0.0', ['node', 'main.js'], {
      CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS: 'true',
    });
    assert.strictEqual(defaultArgs.usageStatistics, false);

    // Test enabling it
    const enabledArgs = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--usage-statistics'],
      {
        CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS: 'true',
      },
    );
    assert.strictEqual(enabledArgs.usageStatistics, false);

    // Test disabling it
    const disabledArgs = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--no-usage-statistics'],
      {
        CHROME_DEVTOOLS_MCP_NO_USAGE_STATISTICS: 'true',
      },
    );
    assert.strictEqual(disabledArgs.usageStatistics, false);
  });

  it('parses performance crux flag', async () => {
    const defaultArgs = parseArguments('1.0.0', ['node', 'main.js']);
    assert.strictEqual(defaultArgs.performanceCrux, true);

    // force enable
    const enabledArgs = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--performance-crux'],
      {},
    );
    assert.strictEqual(enabledArgs.performanceCrux, true);

    const disabledArgs = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--no-performance-crux'],
      {},
    );
    assert.strictEqual(disabledArgs.performanceCrux, false);
  });

  it('parses blocked-url-pattern flags as array', async () => {
    const defaultArgs = parseArguments('1.0.0', ['node', 'main.js']);
    assert.strictEqual(defaultArgs.blockedUrlPattern, undefined);

    const singleArgs = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--blocked-url-pattern=https://example.com/*'],
      {},
    );
    assert.deepStrictEqual(singleArgs.blockedUrlPattern, [
      'https://example.com/*',
    ]);

    const repeatedArgs = parseArguments(
      '1.0.0',
      [
        'node',
        'main.js',
        '--blocked-url-pattern=https://a.com/*',
        '--blocked-url-pattern=https://b.com/*',
      ],
      {},
    );
    assert.deepStrictEqual(repeatedArgs.blockedUrlPattern, [
      'https://a.com/*',
      'https://b.com/*',
    ]);

    const spaceSeparatedArgs = parseArguments(
      '1.0.0',
      [
        'node',
        'main.js',
        '--blocked-url-pattern',
        'https://a.com/*',
        'https://b.com/*',
      ],
      {},
    );
    assert.deepStrictEqual(spaceSeparatedArgs.blockedUrlPattern, [
      'https://a.com/*',
      'https://b.com/*',
    ]);
  });

  it('parses allowed-url-pattern flags as array', async () => {
    const defaultArgs = parseArguments('1.0.0', ['node', 'main.js']);
    assert.strictEqual(defaultArgs.allowedUrlPattern, undefined);

    const singleArgs = parseArguments(
      '1.0.0',
      ['node', 'main.js', '--allowed-url-pattern=https://example.com/*'],
      {},
    );
    assert.deepStrictEqual(singleArgs.allowedUrlPattern, [
      'https://example.com/*',
    ]);

    const repeatedArgs = parseArguments(
      '1.0.0',
      [
        'node',
        'main.js',
        '--allowed-url-pattern=https://a.com/*',
        '--allowed-url-pattern=https://b.com/*',
      ],
      {},
    );
    assert.deepStrictEqual(repeatedArgs.allowedUrlPattern, [
      'https://a.com/*',
      'https://b.com/*',
    ]);

    const spaceSeparatedArgs = parseArguments(
      '1.0.0',
      [
        'node',
        'main.js',
        '--allowed-url-pattern',
        'https://a.com/*',
        'https://b.com/*',
      ],
      {},
    );
    assert.deepStrictEqual(spaceSeparatedArgs.allowedUrlPattern, [
      'https://a.com/*',
      'https://b.com/*',
    ]);
  });
});
