// Copyright (c) 2020, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

import 'dart:convert';
import 'dart:io';

import 'package:path/path.dart' as path;
import 'package:path/path.dart' as p;
import 'package:pub/src/exit_codes.dart';
import 'package:pub/src/io.dart' show EnvironmentKeys;
import 'package:test/test.dart';
import 'package:test_process/test_process.dart';

import '../descriptor.dart' as d;
import '../golden_file.dart';
import '../test_pub.dart';
import 'ensure_pubspec_resolved.dart';

const _commandRunner = 'tool/test-bin/pub_command_runner.dart';

late String snapshot;

final logFile = p.join(d.sandbox, cachePath, 'log', 'pub_log.txt');

/// Runs `dart tool/test-bin/pub_command_runner.dart [args]` and appends the output to [buffer].
Future<void> runEmbeddingToBuffer(
  List<String> args,
  StringBuffer buffer, {
  String? workingDirectory,
  Map<String, String?>? environment,
  dynamic exitCode = 0,
}) async {
  final combinedEnvironment = getPubTestEnvironment();
  (environment ?? {}).forEach((key, value) {
    if (value == null) {
      combinedEnvironment.remove(key);
    } else {
      combinedEnvironment[key] = value;
    }
  });
  final process = await TestProcess.start(
    Platform.resolvedExecutable,
    ['--enable-asserts', snapshot, ...args],
    environment: combinedEnvironment,
    workingDirectory: workingDirectory,
  );
  await process.shouldExit(exitCode);

  final stdoutLines = await process.stdout.rest.toList();
  final stderrLines = await process.stderr.rest.toList();

  buffer.writeln(
    [
      '\$ $_commandRunner ${args.join(' ')}',
      if (stdoutLines.isNotEmpty) _filter(stdoutLines.join('\n')),
      if (stderrLines.isNotEmpty)
        _filter(stderrLines.join('\n'))
            .replaceAll(RegExp('^', multiLine: true), '[E] '),
    ].join('\n'),
  );
  buffer.write('\n');
}

extension on GoldenTestContext {
  /// Runs `dart tool/test-bin/pub_command_runner.dart [args]` and compare to
  /// next section in golden file.
  Future<void> runEmbedding(
    List<String> args, {
    String? workingDirectory,
    Map<String, String>? environment,
    dynamic exitCode = 0,
  }) async {
    final buffer = StringBuffer();
    await runEmbeddingToBuffer(
      args,
      buffer,
      workingDirectory: workingDirectory,
      environment: environment,
      exitCode: exitCode,
    );

    expectNextSection(buffer.toString());
  }
}

Future<void> main() async {
  setUpAll(() async {
    final tempDir = Directory.systemTemp.createTempSync();
    snapshot = path.join(tempDir.path, 'command_runner.dart.snapshot');
    final r = Process.runSync(
      Platform.resolvedExecutable,
      ['--snapshot=$snapshot', _commandRunner],
    );
    expect(r.exitCode, 0, reason: r.stderr as String);
  });

  tearDownAll(() {
    File(snapshot).parent.deleteSync(recursive: true);
  });

  test('Can depend on package:flutter_gen', () async {
    // Regression test for https://github.com/dart-lang/pub/issues/3314.
    final server = await servePackages();
    server.serve(
      'flutter_gen',
      '1.0.0',
      contents: [
        d.dir('bin', [d.file('flutter_gen.dart', 'main() {print("hi");}')])
      ],
    );

    await d.appDir(
      dependencies: {'flutter_gen': '^1.0.0'},
    ).create();
    await pubGet();
    final buffer = StringBuffer();

    await runEmbeddingToBuffer(
      ['run', 'flutter_gen'],
      buffer,
      workingDirectory: d.path(appPath),
      environment: getPubTestEnvironment(),
    );
    expect(buffer.toString(), contains('hi'));
  });

  testWithGolden('run works, though hidden', (ctx) async {
    await servePackages();
    await d.dir(appPath, [
      d.appPubspec(),
      d.dir('bin', [
        d.file('main.dart', '''
import 'dart:io';
main() {
  print('Hi');
  exit(123);
}
''')
      ]),
    ]).create();
    await ctx.runEmbedding(
      ['pub', 'get'],
      workingDirectory: d.path(appPath),
    );
    await ctx.runEmbedding(
      ['pub', 'run', 'bin/main.dart'],
      exitCode: 123,
      workingDirectory: d.path(appPath),
    );
  });

  testWithGolden(
      'logfile is written with --verbose and on unexpected exceptions',
      (context) async {
    final server = await servePackages();
    server.serve('foo', '1.0.0');
    await d.appDir(dependencies: {'foo': 'any'}).create();

    // TODO(sigurdm) This logs the entire verbose trace to a golden file.
    //
    // This is fragile, and can break for all sorts of small reasons. We think
    // this might be worth while having to have at least minimal testing of the
    // verbose stack trace.
    //
    // But if you, future contributor, think this test is annoying: feel free to
    // remove it, or rewrite it to filter out the stack-trace itself, only
    // testing for creation of the file.
    //
    //  It is a fragile test, and we acknowledge that it's usefulness can be
    //  debated...
    await context.runEmbedding(
      ['pub', '--verbose', 'get'],
      workingDirectory: d.path(appPath),
    );
    context.expectNextSection(
      _filter(
        File(logFile).readAsStringSync(),
      ),
    );
    await d.dir('empty').create();
    await context.runEmbedding(
      ['pub', 'fail'],
      workingDirectory: d.path('empty'),
      exitCode: 1,
    );
    context.expectNextSection(
      _filter(
        File(logFile).readAsStringSync(),
      ),
    );
  });

  test('analytics', () async {
    await servePackages()
      ..serve('foo', '1.0.0', deps: {'bar': 'any'})
      ..serve('bar', '1.0.0');
    await d.dir('dep', [
      d.pubspec({
        'name': 'dep',
        'environment': {'sdk': '^3.0.0'}
      })
    ]).create();
    final app = d.dir(appPath, [
      d.appPubspec(
        dependencies: {
          'foo': '1.0.0',
          // The path dependency should not go to analytics.
          'dep': {'path': '../dep'}
        },
      )
    ]);
    await app.create();

    final buffer = StringBuffer();

    await runEmbeddingToBuffer(
      ['pub', 'get'],
      buffer,
      workingDirectory: app.io.path,
      environment: {...getPubTestEnvironment(), '_PUB_LOG_ANALYTICS': 'true'},
    );
    final analytics = buffer
        .toString()
        .split('\n')
        .where((line) => line.startsWith('[E] [analytics]: '))
        .map((line) => json.decode(line.substring('[E] [analytics]: '.length)));
    expect(analytics, {
      {
        'hitType': 'event',
        'message': {
          'category': 'pub-get',
          'action': 'foo',
          'label': '1.0.0',
          'value': 1,
          'cd1': 'direct',
          'ni': '1',
        }
      },
      {
        'hitType': 'event',
        'message': {
          'category': 'pub-get',
          'action': 'bar',
          'label': '1.0.0',
          'value': 1,
          'cd1': 'transitive',
          'ni': '1',
        }
      },
      {
        'hitType': 'timing',
        'message': {
          'variableName': 'resolution',
          'time': isA<int>(),
          'category': 'pub-get',
          'label': null
        }
      },
    });
    // Don't write the logs to file on a normal run.
    expect(File(logFile).existsSync(), isFalse);
  });

  test('`embedding --verbose pub` is verbose', () async {
    await servePackages();
    final buffer = StringBuffer();
    await runEmbeddingToBuffer(['--verbose', 'pub', 'logout'], buffer);
    expect(buffer.toString(), contains('FINE: Pub 3.1.2+3'));
  });

  testWithGolden('--help', (context) async {
    await servePackages();
    await context.runEmbedding(
      ['pub', '--help'],
      workingDirectory: d.path('.'),
    );
  });

  testWithGolden('--color forces colors', (context) async {
    final server = await servePackages();
    server.serve('foo', '1.0.0');
    server.serve('foo', '2.0.0');
    await d.appDir(dependencies: {'foo': '^1.0.0'}).create();
    await context.runEmbedding(
      ['pub', '--no-color', 'get'],
      environment: getPubTestEnvironment(),
      workingDirectory: d.path(appPath),
    );
    await context.runEmbedding(
      ['pub', '--color', 'get'],
      workingDirectory: d.path(appPath),
      environment: getPubTestEnvironment(),
    );
  });

  test('`embedding run` does `pub get` if sdk updated', () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'environment': {'sdk': '^2.18.0'},
        'dependencies': {'foo': '^1.0.0'}
      }),
      d.dir('bin', [
        d.file('myapp.dart', 'main() {print(42);}'),
      ])
    ]).create();

    final server = await servePackages();
    server.serve(
      'foo',
      '1.0.0',
      pubspec: {
        'environment': {'sdk': '^2.18.0'}
      },
    );

    await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '2.18.3'});
    // Deleting the version-listing cache will cause it to be refetched, and the
    // warning will happen.
    File(p.join(globalServer.cachingPath, '.cache', 'foo-versions.json'))
        .deleteSync();
    server.serve(
      'foo',
      '1.0.1',
      pubspec: {
        'environment': {'sdk': '^2.18.0'}
      },
    );

    final buffer = StringBuffer();

    // Just changing the patch version should not trigger a pub get.
    await runEmbeddingToBuffer(
      ['--verbose', 'run', 'myapp'],
      buffer,
      workingDirectory: d.path(appPath),
      environment: {'_PUB_TEST_SDK_VERSION': '2.18.4'},
    );

    expect(
      buffer.toString(),
      allOf(contains('42'), isNot(contains('Resolving dependencies'))),
    );

    File(p.join(globalServer.cachingPath, '.cache', 'foo-versions.json'));
    buffer.clear();

    // Changing the minor version should.
    await runEmbeddingToBuffer(
      ['--verbose', 'run', 'myapp'],
      buffer,
      workingDirectory: d.path(appPath),
      environment: {'_PUB_TEST_SDK_VERSION': '2.19.3'},
    );
    expect(
      buffer.toString(),
      allOf(
        contains('42'),
        contains('Resolving dependencies'),
        contains('1.0.1 available'),
      ),
    );
  });

  test('`embedding run` does not have output when successful and no terminal',
      () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'dependencies': {'foo': '^1.0.0'}
      }),
      d.dir('bin', [
        d.file('myapp.dart', 'main() {print(42);}'),
      ])
    ]).create();

    final server = await servePackages();
    server.serve('foo', '1.0.0');

    final buffer = StringBuffer();
    await runEmbeddingToBuffer(
      ['run', 'myapp'],
      buffer,
      workingDirectory: d.path(appPath),
      environment: {EnvironmentKeys.forceTerminalOutput: '0'},
    );

    expect(
      buffer.toString(),
      allOf(
        isNot(contains('Resolving dependencies...')),
        contains('42'),
      ),
    );
  });
  test('`embedding run` outputs info when successful and has a terminal',
      () async {
    await d.dir(appPath, [
      d.pubspec({
        'name': 'myapp',
        'dependencies': {'foo': '^1.0.0'}
      }),
      d.dir('bin', [
        d.file('myapp.dart', 'main() {print(42);}'),
      ])
    ]).create();

    final server = await servePackages();
    server.serve('foo', '1.0.0');

    final buffer = StringBuffer();
    await runEmbeddingToBuffer(
      ['run', 'myapp'],
      buffer,
      workingDirectory: d.path(appPath),
      environment: {EnvironmentKeys.forceTerminalOutput: '1'},
    );
    expect(
      buffer.toString(),
      allOf(
        contains('Resolving dependencies'),
        contains('42'),
      ),
    );
  });

  test('"pkg" and "packages" will trigger a suggestion of "pub"', () async {
    await servePackages();
    await d.appDir().create();
    for (final command in ['pkg', 'packages']) {
      final buffer = StringBuffer();
      await runEmbeddingToBuffer(
        [command, 'get'],
        buffer,
        workingDirectory: d.path(appPath),
        exitCode: USAGE,
      );
      expect(
        buffer.toString(),
        allOf(
          contains('Did you mean one of these?'),
          contains('  pub'),
        ),
      );
    }
  });

  testEnsurePubspecResolved();
}

String _filter(String input) {
  return input
      .replaceAll(p.toUri(d.sandbox).toString(), r'file://$SANDBOX')
      .replaceAll(d.sandbox, r'$SANDBOX')
      .replaceAll(Platform.pathSeparator, '/')
      .replaceAll(Platform.operatingSystem, r'$OS')
      .replaceAll(globalServer.port.toString(), r'$PORT')
      .replaceAll(
        RegExp(r'^Created:(.*)$', multiLine: true),
        r'Created: $TIME',
      )
      .replaceAll(
        RegExp(r'Generated by pub on (.*)$', multiLine: true),
        r'Generated by pub on $TIME',
      )
      .replaceAll(
        RegExp(r'X-Pub-Session-ID(.*)$', multiLine: true),
        r'X-Pub-Session-ID: $ID',
      )
      .replaceAll(
        RegExp(r'took (.*)$', multiLine: true),
        r'took: $TIME',
      )
      .replaceAll(
        RegExp(r'date: (.*)$', multiLine: true),
        r'date: $TIME',
      )
      .replaceAll(
        RegExp(r'Creating (.*) from stream\.$', multiLine: true),
        r'Creating $FILE from stream',
      )
      .replaceAll(
        RegExp(r'Created (.*) from stream\.$', multiLine: true),
        r'Created $FILE from stream',
      )
      .replaceAll(
        RegExp(
          r'Renaming directory $SANDBOX/cache/_temp/(.*?) to',
          multiLine: true,
        ),
        r'Renaming directory $SANDBOX/cache/_temp/',
      )
      .replaceAll(
        RegExp(r'Extracting .tar.gz stream to (.*?)$', multiLine: true),
        r'Extracting .tar.gz stream to $DIR',
      )
      .replaceAll(
        RegExp(r'Extracted .tar.gz to (.*?)$', multiLine: true),
        r'Extracted .tar.gz to $DIR',
      )
      .replaceAll(
        RegExp(r'Reading binary file (.*?)$', multiLine: true),
        r'Reading binary file $FILE.',
      )
      .replaceAll(
        RegExp(r'Deleting directory (.*)$', multiLine: true),
        r'Deleting directory $DIR',
      )
      .replaceAll(
        RegExp(r'Deleting directory (.*)$', multiLine: true),
        r'Deleting directory $DIR',
      )
      .replaceAll(
        RegExp(r'Resolving dependencies finished (.*)$', multiLine: true),
        r'Resolving dependencies finished ($TIME)',
      )
      .replaceAll(
        RegExp(r'Created temp directory (.*)$', multiLine: true),
        r'Created temp directory $DIR',
      )
      .replaceAll(
        RegExp(r'Renaming directory (.*)$', multiLine: true),
        r'Renaming directory $A to $B',
      )
      .replaceAll(
        RegExp(r'"_fetchedAt":"(.*)"}$', multiLine: true),
        r'"_fetchedAt": "$TIME"}',
      )
      .replaceAll(
        RegExp(r'"generated": "(.*)",$', multiLine: true),
        r'"generated": "$TIME",',
      )
      .replaceAll(
        RegExp(
          r'( |^)(/|[A-Z]:)(.*)/tool/test-bin/pub_command_runner.dart',
          multiLine: true,
        ),
        r' tool/test-bin/pub_command_runner.dart',
      )
      .replaceAll(
        RegExp(r'[ ]{4,}', multiLine: true),
        r'   ',
      )
      .replaceAll(
        RegExp(r' [\d]+:[\d]+ ', multiLine: true),
        r' $LINE:$COL ',
      )
      .replaceAll(
        RegExp(r'Writing \d+ characters', multiLine: true),
        r'Writing $N characters',
      )
      .replaceAll(
        RegExp(r'x-goog-hash(.*)$', multiLine: true),
        r'x-goog-hash: $CHECKSUM_HEADER',
      )
      .replaceAll(
        RegExp(
          r'Computed checksum \d+ for foo 1.0.0 with expected CRC32C of '
          r'\d+\.',
          multiLine: true,
        ),
        r'Computed checksum $CRC32C for foo 1.0.0 with expected CRC32C of '
        r'$CRC32C.',
      )

      /// TODO(sigurdm): This hack suppresses differences in stack-traces
      /// between dart 2.17 and 2.18. Remove when 2.18 is stable.
      .replaceAllMapped(
        RegExp(
          r'(^(.*)pub/src/command.dart \$LINE:\$COL(.*)$)\n\1',
          multiLine: true,
        ),
        (match) => match[1]!,
      );
}
