// 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/dart.dart';
import 'package:pub/src/io.dart';
import 'package:pub_semver/pub_semver.dart';

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

void manifestAndLockfile(GoldenTestContext context) {
  String catFile(String filename) {
    final contents = filterUnstableLines(
        File(p.join(d.sandbox, appPath, filename)).readAsLinesSync());

    return '''
\$ cat $filename
${contents.join('\n')}''';
  }

  context.expectNextSection('''
${catFile('pubspec.yaml')}
${catFile('pubspec.lock')}
''');
}

final snapshot = () async {
  final snapshotFilename = p.absolute(
      p.join('.dart_tool', '_pub', 'dependency_services.dart.snapshot.dart2'));
  final snapshotIncrementalFilename = '$snapshotFilename.incremental';
  await precompile(
      executablePath: p.join('bin', 'dependency_services.dart'),
      outputPath: snapshotFilename,
      incrementalDillOutputPath: snapshotIncrementalFilename,
      name: 'bin/pub.dart',
      packageConfigPath: p.join('.dart_tool', 'package_config.json'));
  return snapshotFilename;
}();

extension on GoldenTestContext {
  Future<void> runDependencyServices(List<String> args, {String? stdin}) async {
    final buffer = StringBuffer();
    buffer.writeln('## Section ${args.join(' ')}');
    final process = await Process.start(
      Platform.resolvedExecutable,
      [
        await snapshot,
        ...args,
      ],
      environment: getPubTestEnvironment(),
      workingDirectory: p.join(d.sandbox, appPath),
    );
    if (stdin != null) {
      process.stdin.write(stdin);
      await process.stdin.flush();
      await process.stdin.close();
    }
    final exitCode = await process.exitCode;

    final pipe = stdin == null ? '' : ' echo ${protectArgument(stdin)} |';
    buffer.writeln([
      '\$$pipe dependency_services ${args.map(protectArgument).join(' ')}',
      ...await outputLines(process.stdout),
      ...(await outputLines(process.stderr)).map((e) => '[STDERR] $e'),
      if (exitCode != 0) '[EXIT CODE] $exitCode',
    ].join('\n'));

    expectNextSection(buffer.toString());
  }
}

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

Future<void> listReportApply(
  GoldenTestContext context,
  List<_PackageVersion> upgrades,
) async {
  manifestAndLockfile(context);
  await context.runDependencyServices(['list']);
  await context.runDependencyServices(['report']);

  final input = json.encode({
    'dependencyChanges': upgrades,
  });

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

Future<void> main() async {
  testWithGolden('Removing transitive', (context) async {
    await servePackages((builder) => builder
      ..serve('foo', '1.2.3', deps: {'transitive': '^1.0.0'})
      ..serve('foo', '2.2.3')
      ..serve('transitive', '1.0.0'));

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {
          'foo': '^1.0.0',
        },
      })
    ]).create();
    await pubGet();
    await listReportApply(context, [
      _PackageVersion('foo', Version.parse('2.2.3')),
      _PackageVersion('transitive', null)
    ]);
  });

  testWithGolden('Compatible', (context) async {
    await servePackages((builder) => builder
      ..serve('foo', '1.2.3')
      ..serve('foo', '2.2.3')
      ..serve('bar', '1.2.3')
      ..serve('bar', '2.2.3'));
    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {
          'foo': '^1.0.0',
          'bar': '^1.0.0',
        },
      })
    ]).create();
    await pubGet();
    globalPackageServer!.add((b) => b.serve('foo', '1.2.4'));
    await listReportApply(context, [
      _PackageVersion('foo', Version.parse('1.2.3')),
      _PackageVersion('transitive', null)
    ]);
  });

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

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {
          'foo': '^1.0.0',
        },
      })
    ]).create();
    await pubGet();
    await listReportApply(context, [
      _PackageVersion('foo', Version.parse('2.2.3')),
      _PackageVersion('transitive', Version.parse('1.0.0'))
    ]);
  });

  testWithGolden('multibreaking', (context) async {
    await servePackages((builder) => builder
      ..serve('foo', '1.0.0')
      ..serve('bar', '1.0.0'));

    await d.dir(appPath, [
      d.pubspec({
        'name': 'app',
        'dependencies': {
          'foo': '^1.0.0',
          'bar': '^1.0.0',
        },
      })
    ]).create();
    await pubGet();
    globalPackageServer!.add((builder) => builder
      ..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('transitive', '1.0.0'));
    await listReportApply(context, [
      _PackageVersion('foo', Version.parse('3.0.1'),
          constraint: VersionConstraint.parse('^3.0.0')),
      _PackageVersion('bar', Version.parse('2.0.0'))
    ]);
  });
}

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

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