// 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 p;
import 'package:pub/src/io.dart';
import 'package:pub_semver/pub_semver.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'package:test/test.dart';
import 'package:yaml/yaml.dart';
import 'package:yaml_edit/yaml_edit.dart';

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

void manifestAndLockfile(GoldenTestContext context, List<String> workspace) {
  String catFile(String filename) {
    final path = p.join(d.sandbox, appPath, filename);
    final normalizedFilename = p.posix.joinAll(p.split(p.normalize(filename)));
    if (File(path).existsSync()) {
      final contents = File(path).readAsLinesSync().map(filterUnstableText);

      return '''
\$ cat $normalizedFilename
${contents.join('\n')}''';
    } else {
      return '''
\$ cat $normalizedFilename
No such file $normalizedFilename.''';
    }
  }

  context.expectNextSection('''
${workspace.map((path) => catFile(p.join(path, 'pubspec.yaml'))).join('\n')}
${catFile('pubspec.lock')}
''');
}

late final String snapshot;

extension on GoldenTestContext {
  /// Returns the stdout.
  Future<String> runDependencyServices(
    List<String> args, {
    String stdin = '',
    Map<String, String>? environment,
  }) async {
    final buffer = StringBuffer();
    buffer.writeln('## Section ${args.join(' ')}');
    final process = await Process.start(
      Platform.resolvedExecutable,
      ['--enable-asserts', snapshot, '--verbose', ...args],
      environment: {
        ...getPubTestEnvironment(),
        '_PUB_TEST_DEFAULT_HOSTED_URL': globalServer.url,
        ...?environment,
      },
      workingDirectory: p.join(d.sandbox, appPath),
    );
    process.stdin.write(stdin);
    await process.stdin.flush();
    await process.stdin.close();

    final outLines = outputLines(process.stdout);
    final errLines = outputLines(process.stderr);
    final exitCode = await process.exitCode;

    final pipe = ' echo ${filterUnstableText(escapeShellArgument(stdin))} |';
    final argString = args.map(escapeShellArgument).join(' ');
    buffer.writeln(
      [
        '\$$pipe dependency_services $argString',
        ...await outLines,
        ...(await errLines).map((e) => '[STDERR] $e'),
        if (exitCode != 0) '[EXIT CODE] $exitCode',
      ].join('\n'),
    );

    expectNextSection(buffer.toString());
    return (await outLines).join('\n');
  }
}

Future<Iterable<String>> outputLines(Stream<List<int>> stream) async {
  final s = await utf8.decodeStream(stream);
  if (s.isEmpty) return [];
  return s.split('\n').map(filterUnstableText);
}

Future<void> _listReportApply(
  GoldenTestContext context,
  List<_PackageVersion> upgrades, {
  List<String> workspace = const ['.'],
  void Function(Map)? reportAssertions,
  Map<String, String>? environment,
}) async {
  manifestAndLockfile(context, workspace);
  await context.runDependencyServices(['list'], environment: environment);
  final report = await context.runDependencyServices([
    'report',
  ], environment: environment);
  if (reportAssertions != null) {
    reportAssertions(json.decode(report) as Map);
  }
  final input = json.encode({'dependencyChanges': upgrades});

  await context.runDependencyServices(
    ['apply'],
    stdin: input,
    environment: environment,
  );
  manifestAndLockfile(context, workspace);
}

Future<void> _reportWithForbidden(
  GoldenTestContext context,
  Map<String, List<String>> disallowedVersions, {
  void Function(Map)? resultAssertions,
  String? targetPackage,
}) async {
  manifestAndLockfile(context, ['.']);
  final input = json.encode({
    'target': targetPackage,
    'disallowed': [
      for (final e in disallowedVersions.entries)
        {
          'name': e.key,
          'url': globalServer.url,
          'versions': e.value.map((d) => {'range': d}).toList(),
        },
    ],
  });
  final report = await context.runDependencyServices(['report'], stdin: input);
  if (resultAssertions != null) {
    resultAssertions(json.decode(report) as Map);
  }

  // await context.runDependencyServices(['apply'], stdin: input);
  manifestAndLockfile(context, ['.']);
}

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

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

  testWithGolden('Removing transitive', (context) async {
    final server =
        (await servePackages())
          ..serve('foo', '1.2.3', deps: {'transitive': '^1.0.0'})
          ..serve('foo', '2.2.3')
          ..serve('transitive', '1.0.0')
          ..serveContentHashes = true;

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {'foo': '^1.0.0'},
      }),
    ]).create();
    await pubGet();
    server.dontAllowDownloads();
    await _listReportApply(
      context,
      [_PackageVersion('foo', '2.2.3'), _PackageVersion('transitive', null)],
      reportAssertions: (report) {
        expect(findChangeVersion(report, 'singleBreaking', 'foo'), '2.2.3');
        expect(findChangeVersion(report, 'singleBreaking', 'transitive'), null);
      },
    );
  });

  testWithGolden('Ignoring version', (context) async {
    final server = await servePackages();
    server.serve('foo', '1.0.0');

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {'foo': '^1.0.0'},
      }),
    ]).create();
    await pubGet();

    server.serve('foo', '1.0.1'); // should get this.
    server.serve('foo', '1.0.2'); // ignored
    server.serve('foo', '1.0.3', deps: {'transitive': '1.0.0'});
    server.serve('transitive', '1.0.0'); // ignored
    await _reportWithForbidden(
      context,
      {
        'foo': ['1.0.2'],
        'transitive': ['1.0.0'],
      },
      resultAssertions: (report) {
        expect(findChangeVersion(report, 'compatible', 'foo'), '1.0.1');
      },
    );
  });

  testWithGolden('No pubspec.lock', (context) async {
    final server =
        (await servePackages())
          ..serve('foo', '1.2.3', deps: {'transitive': '^1.0.0'})
          ..serve('foo', '2.2.3')
          ..serve('transitive', '1.0.0')
          ..serveContentHashes = true;

    await d.git('bar.git', [d.libPubspec('bar', '1.0.0')]).create();

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {
          'foo': '^1.0.0',
          'bar': {
            'git': {'url': '../bar.git'},
          },
        },
      }),
    ]).create();

    server.dontAllowDownloads();
    await _listReportApply(context, [
      _PackageVersion('foo', '2.2.3'),
      _PackageVersion('transitive', null),
    ]);
  });

  testWithGolden('Compatible', (context) async {
    final server =
        (await servePackages())
          ..serve('foo', '1.2.3')
          ..serve('foo', '2.2.3')
          ..serve('bar', '1.2.3')
          ..serve('bar', '2.2.3')
          ..serve('boo', '1.2.3')
          ..serveContentHashes = true;

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {'foo': '^1.0.0', 'bar': '^1.0.0', 'boo': '^1.0.0'},
      }),
    ]).create();
    await pubGet();
    server.serve('foo', '1.2.4');
    server.serve('boo', '1.2.4');

    server.dontAllowDownloads();

    await _listReportApply(
      context,
      [_PackageVersion('foo', '1.2.4')],
      reportAssertions: (report) {
        expect(findChangeVersion(report, 'compatible', 'foo'), '1.2.4');
      },
    );
  });

  testWithGolden('Preserves no content-hashes', (context) async {
    final server =
        (await servePackages())
          ..serve('foo', '1.2.3')
          ..serve('foo', '2.2.3')
          ..serve('bar', '1.2.3')
          ..serve('bar', '2.2.3')
          ..serve('boo', '1.2.3')
          ..serveContentHashes = true;

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {'foo': '^1.0.0', 'bar': '^1.0.0', 'boo': '^1.0.0'},
      }),
    ]).create();
    await pubGet();
    final lockFile = File(path(p.join(appPath, 'pubspec.lock')));
    final lockFileYaml = YamlEditor(lockFile.readAsStringSync());
    for (final p in (lockFileYaml.parseAt(['packages']) as YamlMap).entries) {
      lockFileYaml.remove(['packages', p.key, 'description', 'sha256']);
    }
    lockFile.writeAsStringSync(lockFileYaml.toString());

    server.serve('foo', '1.2.4');
    server.serve('boo', '1.2.4');

    server.dontAllowDownloads();

    await _listReportApply(context, [_PackageVersion('foo', '1.2.4')]);
  });

  testWithGolden('Preserves pub.dartlang.org as hosted url', (context) async {
    final server =
        (await servePackages())
          ..serve(r'foo', '1.2.3')
          ..serve(r'bar', '1.2.3')
          ..serveContentHashes = true;

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {'foo': '^1.0.0', 'bar': '^1.0.0'},
      }),
    ]).create();
    await pubGet();
    final lockFile = File(path(p.join(appPath, 'pubspec.lock')));
    final lockFileYaml = YamlEditor(lockFile.readAsStringSync());
    for (final p in (lockFileYaml.parseAt(['packages']).value as Map).entries) {
      lockFileYaml.update([
        'packages',
        p.key,
        'description',
        'url',
      ], 'https://pub.dartlang.org');
    }
    lockFile.writeAsStringSync(lockFileYaml.toString());

    server.serve('foo', '1.2.4');
    server.serve('boo', '1.2.4');

    await _listReportApply(context, [_PackageVersion('foo', '1.2.4')]);
  });

  testWithGolden('Adding transitive', (context) async {
    final server =
        (await servePackages())
          ..serve('foo', '1.2.3')
          ..serve('foo', '2.2.3', deps: {'transitive': '^1.0.0'})
          ..serve('transitive', '1.0.0')
          ..serveContentHashes = true;

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {'foo': '^1.0.0'},
      }),
    ]).create();
    await pubGet();
    server.dontAllowDownloads();

    await _listReportApply(
      context,
      [_PackageVersion('foo', '2.2.3'), _PackageVersion('transitive', '1.0.0')],
      reportAssertions: (report) {
        expect(findChangeVersion(report, 'singleBreaking', 'foo'), '2.2.3');
        expect(
          findChangeVersion(report, 'singleBreaking', 'transitive'),
          '1.0.0',
        );
      },
    );
  });

  testWithGolden('multibreaking', (context) async {
    final server =
        (await servePackages())
          ..serve('foo', '1.0.0')
          ..serve('bar', '1.0.0')
          ..serve('baz', '1.0.0')
          ..serveContentHashes = true;

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {
          'foo': '^1.0.0',
          'bar': '^1.0.0',
          // Pinned version. See that the widened constraint is correct.
          'baz': '1.0.0',
        },
      }),
    ]).create();
    await pubGet();
    server
      ..serve('foo', '1.5.0') // compatible
      ..serve('foo', '2.0.0') // single breaking
      ..serve('foo', '3.0.0', deps: {'bar': '^2.0.0'}) // multi breaking
      ..serve('foo', '3.0.1', deps: {'bar': '^2.0.0'})
      ..serve('bar', '2.0.0', deps: {'foo': '^3.0.0'})
      ..serve('baz', '1.1.0');

    server.dontAllowDownloads();

    await _listReportApply(
      context,
      [
        _PackageVersion(
          'foo',
          '3.0.1',
          constraint: VersionConstraint.parse('^3.0.0'),
        ),
        _PackageVersion('bar', '2.0.0'),
      ],
      reportAssertions: (report) {
        expect(findChangeVersion(report, 'multiBreaking', 'foo'), '3.0.1');
        expect(findChangeVersion(report, 'multiBreaking', 'bar'), '2.0.0');
      },
    );
  });
  testWithGolden('Relative paths are allowed', (context) async {
    // We cannot update path-dependencies, but they should be allowed.
    final server = await servePackages();
    server.serve('foo', '1.0.0');
    await d.dir('bar', [d.libPubspec('bar', '1.0.0')]).create();

    await d
        .appDir(
          dependencies: {
            'foo': '^1.0.0',
            'bar': {'path': '../bar'},
          },
        )
        .create();
    await pubGet();
    server.serve('foo', '2.0.0');
    await _listReportApply(
      context,
      [
        _PackageVersion(
          'foo',
          '2.0.0',
          constraint: VersionConstraint.parse('^2.0.0'),
        ),
      ],
      reportAssertions: (report) {
        expect(findChangeVersion(report, 'multiBreaking', 'foo'), '2.0.0');
      },
    );
  });

  testWithGolden('Can update a git package', (context) async {
    await servePackages();
    await d.git('foo.git', [d.libPubspec('foo', '1.0.0')]).create();
    await d.git('bar.git', [d.libPubspec('bar', '1.0.0')]).create();

    await d
        .appDir(
          dependencies: {
            'foo': {
              'git': {'url': '../foo.git'},
            },
            'bar': {
              // A git dependency with a version constraint.
              'git': {'url': '../bar.git'},
              'version': '^1.0.0',
            },
          },
        )
        .create();
    await pubGet();
    final secondVersion = d.git('foo.git', [d.libPubspec('foo', '2.0.0')]);
    await secondVersion.commit();
    final newRef = await secondVersion.revParse('HEAD');

    final barSecondVersion = d.git('bar.git', [d.libPubspec('bar', '2.0.0')]);
    await barSecondVersion.commit();

    await _listReportApply(
      context,
      [_PackageVersion('foo', newRef)],
      reportAssertions: (report) {
        expect(findChangeVersion(report, 'multiBreaking', 'foo'), newRef);
      },
    );
  });

  testWithGolden('Finds smallest possible upgrade', (context) async {
    final server = await servePackages();
    server.serve('foo', '1.1.1'); // This version will be disallowed.

    await d.appDir(dependencies: {'foo': '^1.0.0'}).create();
    await pubGet();
    server.serve(
      'foo',
      '1.0.0',
    ); // We don't want the downgrade to go below the current.

    server.serve(
      'foo',
      '1.1.2',
    ); // This will also be disallowed, a minimal update should not find this.
    server.serve('foo', '1.1.3'); // We would like this to be the new version.
    server.serve('foo', '1.1.4'); // This version would not be a minimal update.

    await _reportWithForbidden(
      context,
      {
        'foo': ['1.1.1', '1.1.2'],
      },
      targetPackage: 'foo',
      resultAssertions: (r) {
        expect(findChangeVersion(r, 'smallestUpdate', 'foo'), '1.1.3');
      },
    );
  });

  testWithGolden('Smallest possible upgrade can upgrade beyond breaking', (
    context,
  ) async {
    final server = await servePackages();
    server.serve('foo', '1.1.1'); // This version will be disallowed.

    await d.appDir(dependencies: {'foo': '^1.0.0'}).create();
    await pubGet();

    server.serve(
      'foo',
      '2.0.0',
    ); // This will also be disallowed, a minimal update should not find this.
    server.serve('foo', '2.0.1'); // We would like this to be the new version.
    server.serve('foo', '2.0.2'); // This version would not be a minimal update.

    await _reportWithForbidden(
      context,
      {
        'foo': ['1.1.1', '2.0.0'],
      },
      targetPackage: 'foo',
      resultAssertions: (r) {
        expect(findChangeVersion(r, 'smallestUpdate', 'foo'), '2.0.1');
      },
    );
  });

  testWithGolden(
    'Smallest possible upgrade can upgrade other packages if needed',
    (context) async {
      final server = await servePackages();
      server.serve('bar', '1.0.0');
      server.serve('bar', '2.0.0');
      server.serve('bar', '2.2.0');

      server.serve(
        'foo',
        '1.1.1',
        deps: {'bar': '^1.0.0'},
      ); // This version will be disallowed.

      await d.appDir(dependencies: {'foo': '^1.0.0', 'bar': '^1.0.0'}).create();
      await pubGet();

      server.serve(
        'foo',
        '2.0.0',
        deps: {'bar': '^2.0.0'},
      ); // This will also be disallowed, a minimal update should not find this.
      server.serve(
        'foo',
        '2.0.1',
        deps: {'bar': '^2.0.0'},
      ); // We would like this to be the new version.
      server.serve(
        'foo',
        '2.0.2',
        deps: {'bar': '^2.0.0'},
      ); // This version would not be a minimal update.

      await _reportWithForbidden(
        context,
        {
          'foo': ['1.1.1', '2.0.0'],
          'bar': ['2.0.0'],
        },
        targetPackage: 'foo',
        resultAssertions: (r) {
          expect(findChangeVersion(r, 'smallestUpdate', 'foo'), '2.0.1');
          expect(findChangeVersion(r, 'smallestUpdate', 'bar'), '2.2.0');
        },
      );
    },
  );

  testWithGolden('can upgrade workspaces', (context) async {
    (await servePackages())
      ..serve('foo', '1.2.3')
      ..serve('foo', '2.2.3', deps: {'transitive': '^1.0.0'})
      ..serve('bar', '1.2.3')
      ..serve('bar', '2.2.3')
      ..serve('only_a', '1.0.0')
      ..serve('only_a', '2.0.0')
      ..serve('dev', '1.0.0')
      ..serve('dev', '2.0.0')
      ..serve('transitive', '1.0.0')
      ..serveContentHashes = true;

    await dir(appPath, [
      libPubspec(
        'myapp',
        '1.2.3',
        extras: {
          'workspace': ['pkgs/a'],
        },
        deps: {'foo': '^1.0.0', 'bar': '^1.0.0'},
        sdk: '^3.5.0',
      ),
      dir('pkgs', [
        dir('a', [
          libPubspec(
            'a',
            '1.1.1',
            deps: {'bar': '>=1.2.0 <1.5.0', 'only_a': '^1.0.0'},
            devDeps: {'foo': '^1.2.0', 'dev': '^1.0.0'},
            resolutionWorkspace: true,
          ),
        ]),
      ]),
    ]).create();
    await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'});

    final result = await Process.run(
      Platform.resolvedExecutable,
      [snapshot, 'list'],
      environment: {
        ...getPubTestEnvironment(),
        '_PUB_TEST_SDK_VERSION': '3.5.0',
      },
      workingDirectory: p.join(d.sandbox, appPath, 'pkgs', 'a'),
    );

    expect(
      result.stderr,
      contains('Only apply dependency_services to the root of the workspace.'),
    );
    expect(result.exitCode, 1);

    await _listReportApply(
      context,
      [
        _PackageVersion('foo', '2.2.3'),
        _PackageVersion('transitive', '1.0.0'),
        _PackageVersion(
          'only_a',
          '2.0.0',
          constraint: VersionConstraint.parse('^2.0.0'),
        ),
      ],
      workspace: ['.', p.join('pkgs', 'a')],
      reportAssertions: (report) {
        expect(findChangeVersion(report, 'singleBreaking', 'foo'), '2.2.3');
        expect(
          findChangeVersion(report, 'singleBreaking', 'transitive'),
          '1.0.0',
        );
      },
      environment: {'_PUB_TEST_SDK_VERSION': '3.5.0'},
    );
  });
}

String? findChangeVersion(dynamic json, String updateType, String name) {
  return dig<String?>(json, [
    'dependencies',
    ('name', 'foo'),
    updateType,
    ('name', name),
    'version',
  ]);
}

class _PackageVersion {
  String name;
  String? version;
  VersionConstraint? constraint;
  _PackageVersion(this.name, this.version, {this.constraint});

  Map<String, Object?> toJson() => {
    'name': name,
    'version': version,
    if (constraint != null) 'constraint': constraint.toString(),
  };
}

extension on PackageServer {
  ///Check that nothing is downloaded.
  void dontAllowDownloads() {
    // This testing logic is a bit fragile, if we change the pattern for pattern
    // for the download URL then this will pass silently. There isn't much we
    // can / should do about it. Just accept the limitations, and remove it if
    // the test becomes useless.
    handle(RegExp(r'/.+\.tar\.gz'), (request) {
      return shelf.Response.notFound(
        'This test should not download archives! Requested ${request.url}',
      );
    });
  }
}
