// Copyright (c) 2015, 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.

// @dart=2.10

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

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

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

void main() {
  setUp(() async {
    await servePackages((builder) {
      builder.serve('foo', '1.0.0');
      builder.serve('foo', '2.0.0');
    });

    await d.dir(appPath, [
      d.appPubspec(),
      d.dir('web', []),
      d.dir('bin', [d.file('script.dart', "main() => print('hello!');")])
    ]).create();

    await pubGet();
  });

  test(
      'does not require a pub get if a `flutter_gen` package is injected into package_config.json',
      () async {
    await d.dir('bar', [
      d.pubspec({'name': 'bar'})
    ]).create();
    await d.dir(appPath, [
      d.appPubspec({
        'bar': {'path': '../bar'}
      })
    ]).create();

    await pubGet();

    final packageConfig =
        p.join(d.sandbox, 'myapp', '.dart_tool', 'package_config.json');
    final contents = json.decode(readTextFile(packageConfig));
    contents['packages'].add({
      'name': 'flutter_gen',
      'rootUri': '.dart_tool/flutter_gen',
      'languageVersion': '2.8',
    });
    writeTextFile(packageConfig, json.encode(contents));

    await runPub(args: ['run', 'bin/script.dart'], output: 'hello!');
  });
  group('requires the user to run pub get first if', () {
    group("there's no lockfile", () {
      setUp(() {
        deleteEntry(p.join(d.sandbox, 'myapp/pubspec.lock'));
      });

      _requiresPubGet(
          'No pubspec.lock file found, please run "pub get" first.');
    });

    group("there's no package_config.json", () {
      setUp(() {
        deleteEntry(p.join(d.sandbox, 'myapp/.dart_tool/package_config.json'));
      });

      _requiresPubGet(
          'No .dart_tool/package_config.json file found, please run "pub get".');
    });

    group('the pubspec has a new dependency', () {
      setUp(() async {
        await d.dir('foo', [d.libPubspec('foo', '1.0.0')]).create();

        await d.dir(appPath, [
          d.appPubspec({
            'foo': {'path': '../foo'}
          })
        ]).create();

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.yaml');
      });

      _requiresPubGet('The pubspec.yaml file has changed since the '
          'pubspec.lock file was generated, please run "pub get" again.');
    });

    group('the lockfile has a dependency from the wrong source', () {
      setUp(() async {
        await d.dir(appPath, [
          d.appPubspec({'foo': '1.0.0'})
        ]).create();

        await pubGet();

        await createLockFile(appPath, dependenciesInSandBox: ['foo']);

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.yaml');
      });

      _requiresPubGet('The pubspec.yaml file has changed since the '
          'pubspec.lock file was generated, please run "pub get" again.');
    });

    group('the lockfile has a dependency from an unknown source', () {
      setUp(() async {
        await d.dir(appPath, [
          d.appPubspec({'foo': '1.0.0'})
        ]).create();

        await pubGet();

        await d.dir(appPath, [
          d.file(
              'pubspec.lock',
              yaml({
                'packages': {
                  'foo': {
                    'description': 'foo',
                    'version': '1.0.0',
                    'source': 'sdk'
                  }
                }
              }))
        ]).create();

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.yaml');
      });

      _requiresPubGet('The pubspec.yaml file has changed since the '
          'pubspec.lock file was generated, please run "pub get" again.');
    });

    group('the lockfile has a dependency with the wrong description', () {
      setUp(() async {
        await d.dir('bar', [d.libPubspec('foo', '1.0.0')]).create();

        await d.dir(appPath, [
          d.appPubspec({
            'foo': {'path': '../bar'}
          })
        ]).create();

        await pubGet();

        await createLockFile(appPath, dependenciesInSandBox: ['foo']);

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.yaml');
      });

      _requiresPubGet('The pubspec.yaml file has changed since the '
          'pubspec.lock file was generated, please run "pub get" again.');
    });

    group('the pubspec has an incompatible version of a dependency', () {
      setUp(() async {
        await d.dir(appPath, [
          d.appPubspec({'foo': '1.0.0'})
        ]).create();

        await pubGet();

        await d.dir(appPath, [
          d.appPubspec({'foo': '2.0.0'})
        ]).create();

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.yaml');
      });

      _requiresPubGet('The pubspec.yaml file has changed since the '
          'pubspec.lock file was generated, please run "pub get" again.');
    });

    group(
        'the lockfile is pointing to an unavailable package with a newer '
        'pubspec', () {
      setUp(() async {
        await d.dir(appPath, [
          d.appPubspec({'foo': '1.0.0'})
        ]).create();

        await pubGet();

        deleteEntry(p.join(d.sandbox, cachePath));

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.yaml');
      });

      _requiresPubGet('The pubspec.yaml file has changed since the '
          'pubspec.lock file was generated, please run "pub get" again.');
    });

    group(
        'the lockfile is pointing to an unavailable package with an older '
        '.packages', () {
      setUp(() async {
        await d.dir(appPath, [
          d.appPubspec({'foo': '1.0.0'})
        ]).create();

        await pubGet();

        deleteEntry(p.join(d.sandbox, cachePath));

        // Ensure that the lockfile looks newer than the .packages file.
        await _touch('pubspec.lock');
      });

      _requiresPubGet('The pubspec.lock file has changed since the .packages '
          'file was generated, please run "pub get" again.');
    });

    group("the lockfile has a package that the .packages file doesn't", () {
      setUp(() async {
        await d.dir('foo', [d.libPubspec('foo', '1.0.0')]).create();

        await d.dir(appPath, [
          d.appPubspec({
            'foo': {'path': '../foo'}
          })
        ]).create();

        await pubGet();

        await createPackagesFile(appPath);

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.lock');
      });

      _requiresPubGet('The pubspec.lock file has changed since the .packages '
          'file was generated, please run "pub get" again.');
    });

    group('the .packages file has a package with a non-file URI', () {
      setUp(() async {
        await d.dir('foo', [d.libPubspec('foo', '1.0.0')]).create();

        await d.dir(appPath, [
          d.appPubspec({
            'foo': {'path': '../foo'}
          })
        ]).create();

        await pubGet();

        await d.dir(appPath, [
          d.file('.packages', '''
myapp:lib
foo:http://example.com/
''')
        ]).create();

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.lock');
      });

      _requiresPubGet('The pubspec.lock file has changed since the .packages '
          'file was generated, please run "pub get" again.');
    });

    group('the .packages file points to the wrong place', () {
      setUp(() async {
        await d.dir('bar', [d.libPubspec('foo', '1.0.0')]).create();

        await d.dir(appPath, [
          d.appPubspec({
            'foo': {'path': '../bar'}
          })
        ]).create();

        await pubGet();

        await createPackagesFile(appPath, dependenciesInSandBox: ['foo']);

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.lock');
      });

      _requiresPubGet('The pubspec.lock file has changed since the .packages '
          'file was generated, please run "pub get" again.');
    });

    group('the package_config.json file points to the wrong place', () {
      setUp(() async {
        await d.dir('bar', [d.libPubspec('foo', '1.0.0')]).create();

        await d.dir(appPath, [
          d.appPubspec({
            'foo': {'path': '../bar'}
          })
        ]).create();

        await pubGet();

        await d.dir(appPath, [
          d.packageConfigFile([
            d.packageConfigEntry(
              name: 'foo',
              path: '../foo', // this is the wrong path
            ),
            d.packageConfigEntry(
              name: 'myapp',
              path: '.',
            ),
          ]),
        ]).create();

        // Ensure that the pubspec looks newer than the lockfile.
        await _touch('pubspec.lock');
      });

      _requiresPubGet('The pubspec.lock file has changed since the '
          '.dart_tool/package_config.json file was generated, '
          'please run "pub get" again.');
    });

    group("the lock file's SDK constraint doesn't match the current SDK", () {
      setUp(() async {
        // Avoid using a path dependency because it triggers the full validation
        // logic. We want to be sure SDK-validation works without that logic.
        globalPackageServer.add((builder) {
          builder.serve('foo', '3.0.0', pubspec: {
            'environment': {'sdk': '>=1.0.0 <2.0.0'}
          });
        });

        await d.dir(appPath, [
          d.pubspec({
            'name': 'myapp',
            'dependencies': {'foo': '3.0.0'},
            'environment': {
              'sdk': '>=1.0.0 <2.0.0',
            },
          }),
        ]).create();

        await pubGet(environment: {'_PUB_TEST_SDK_VERSION': '1.2.3+4'});
      });

      _requiresPubGet("Dart 0.1.2+3 is incompatible with your dependencies' "
          'SDK constraints. Please run \"pub get\" again.');
    });

    test(
        "the lock file's Flutter SDK constraint doesn't match the "
        'current Flutter SDK', () async {
      // Avoid using a path dependency because it triggers the full validation
      // logic. We want to be sure SDK-validation works without that logic.
      globalPackageServer.add((builder) {
        builder.serve('foo', '3.0.0', pubspec: {
          'environment': {'flutter': '>=1.0.0 <2.0.0'}
        });
      });

      await d.dir('flutter', [d.file('version', '1.2.3')]).create();

      await d.dir(appPath, [
        d.appPubspec({'foo': '3.0.0'})
      ]).create();

      await pubGet(environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')});

      await d.dir('flutter', [d.file('version', '0.9.0')]).create();

      // Run pub manually here because otherwise we don't have access to
      // d.sandbox.
      await runPub(
          args: ['run', 'script'],
          environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')},
          error: "Flutter 0.9.0 is incompatible with your dependencies' SDK "
              'constraints. Please run "pub get" again.',
          exitCode: exit_codes.DATA);
    });

    group("a path dependency's dependency doesn't match the lockfile", () {
      setUp(() async {
        await d.dir('bar', [
          d.libPubspec('bar', '1.0.0', deps: {'foo': '1.0.0'})
        ]).create();

        await d.dir(appPath, [
          d.appPubspec({
            'bar': {'path': '../bar'}
          })
        ]).create();

        await pubGet();

        // Update bar's pubspec without touching the app's.
        await d.dir('bar', [
          d.libPubspec('bar', '1.0.0', deps: {'foo': '2.0.0'})
        ]).create();
      });

      _requiresPubGet('${p.join('..', 'bar', 'pubspec.yaml')} has changed '
          'since the pubspec.lock file was generated, please run "pub get" '
          'again.');
    });

    group(
        "a path dependency's language version doesn't match the package_config.json",
        () {
      setUp(() async {
        await d.dir('bar', [
          d.libPubspec(
            'bar',
            '1.0.0',
            deps: {'foo': '1.0.0'},
            // Creates language version requirement 0.0
            sdk: '>= 0.0.1 <=0.9.9', // tests runs with '0.1.2+3'
          ),
        ]).create();

        await d.dir(appPath, [
          d.appPubspec({
            'bar': {'path': '../bar'}
          })
        ]).create();

        await pubGet();

        // Update bar's pubspec without touching the app's.
        await d.dir('bar', [
          d.libPubspec(
            'bar',
            '1.0.0',
            deps: {'foo': '1.0.0'},
            // Creates language version requirement 0.1
            sdk: '>= 0.1.0 <=0.9.9', // tests runs with '0.1.2+3'
          ),
        ]).create();
      });

      _requiresPubGet('${p.join('..', 'bar', 'pubspec.yaml')} has changed '
          'since the pubspec.lock file was generated, please run "pub get" '
          'again.');
    });
  });

  group("doesn't require the user to run pub get first if", () {
    group(
        'the pubspec is older than the lockfile which is older than the '
        'packages file, even if the contents are wrong', () {
      setUp(() async {
        await d.dir(appPath, [
          d.appPubspec({'foo': '1.0.0'})
        ]).create();
        // Ensure we get a new mtime (mtime is only reported with 1s precision)
        await _touch('pubspec.yaml');

        await _touch('pubspec.lock');
        await _touch('.packages');
        await _touch('.dart_tool/package_config.json');
      });

      _runsSuccessfully(runDeps: false);
    });

    group("the pubspec is newer than the lockfile, but they're up-to-date", () {
      setUp(() async {
        await d.dir(appPath, [
          d.appPubspec({'foo': '1.0.0'})
        ]).create();

        await pubGet();

        await _touch('pubspec.yaml');
      });

      _runsSuccessfully();
    });

    // Regression test for #1416
    group('a path dependency has a dependency on the root package', () {
      setUp(() async {
        await d.dir('foo', [
          d.libPubspec('foo', '1.0.0', deps: {'myapp': 'any'})
        ]).create();

        await d.dir(appPath, [
          d.appPubspec({
            'foo': {'path': '../foo'}
          })
        ]).create();

        await pubGet();

        await _touch('pubspec.lock');
      });

      _runsSuccessfully();
    });

    group("the lockfile is newer than package_config.json, but it's up-to-date",
        () {
      setUp(() async {
        await d.dir(appPath, [
          d.appPubspec({'foo': '1.0.0'})
        ]).create();

        await pubGet();

        await _touch('pubspec.lock');
      });

      _runsSuccessfully();
    });

    group("an overridden dependency's SDK constraint is unmatched", () {
      setUp(() async {
        globalPackageServer.add((builder) {
          builder.serve('bar', '1.0.0', pubspec: {
            'environment': {'sdk': '0.0.0-fake'}
          });
        });

        await d.dir(appPath, [
          d.pubspec({
            'name': 'myapp',
            'dependency_overrides': {'bar': '1.0.0'}
          })
        ]).create();

        await pubGet();

        await _touch('pubspec.lock');
      });

      _runsSuccessfully();
    });

    test('the lock file has a Flutter SDK but Flutter is unavailable',
        () async {
      // Avoid using a path dependency because it triggers the full validation
      // logic. We want to be sure SDK-validation works without that logic.
      globalPackageServer.add((builder) {
        builder.serve('foo', '3.0.0', pubspec: {
          'environment': {'flutter': '>=1.0.0 <2.0.0'}
        });
      });

      await d.dir('flutter', [d.file('version', '1.2.3')]).create();

      await d.dir(appPath, [
        d.appPubspec({'foo': '3.0.0'})
      ]).create();

      await pubGet(environment: {'FLUTTER_ROOT': p.join(d.sandbox, 'flutter')});

      await d.dir('flutter', [d.file('version', '2.4.6')]).create();

      // Run pub manually here because otherwise we don't have access to
      // d.sandbox.
      await runPub(args: ['run', 'bin/script.dart']);
    });
  });
}

/// Runs every command that care about the world being up-to-date, and asserts
/// that it prints [message] as part of its error.
void _requiresPubGet(String message) {
  for (var command in ['run', 'deps']) {
    test('for pub $command', () {
      var args = [command];
      if (command == 'run') args.add('script');

      return runPub(
          args: args, error: contains(message), exitCode: exit_codes.DATA);
    });
  }
}

/// Ensures that pub doesn't require "pub get" for the current package.
///
/// If [runDeps] is false, `pub deps` isn't included in the test. This is
/// sometimes not desirable, since it uses slightly stronger checks for pubspec
/// and lockfile consistency.
void _runsSuccessfully({bool runDeps = true}) {
  var commands = ['run'];
  if (runDeps) commands.add('deps');

  for (var command in commands) {
    test('for pub $command', () async {
      var args = [command];
      if (command == 'run') args.add('bin/script.dart');

      await runPub(args: args);

      // If pub determines that everything is up-to-date, it should set the
      // mtimes to indicate that.
      var pubspecModified =
          File(p.join(d.sandbox, 'myapp/pubspec.yaml')).lastModifiedSync();
      var lockFileModified =
          File(p.join(d.sandbox, 'myapp/pubspec.lock')).lastModifiedSync();
      var packagesModified =
          File(p.join(d.sandbox, 'myapp/.packages')).lastModifiedSync();
      var packageConfigModified =
          File(p.join(d.sandbox, 'myapp/.dart_tool/package_config.json'))
              .lastModifiedSync();

      expect(!pubspecModified.isAfter(lockFileModified), isTrue);
      expect(!lockFileModified.isAfter(packagesModified), isTrue);
      expect(!lockFileModified.isAfter(packageConfigModified), isTrue);
    });
  }
}

/// Schedules a non-semantic modification to [path].
Future _touch(String path) async {
  // Delay a bit to make sure the modification times are noticeably different.
  // 1s seems to be the finest granularity that dart:io reports.
  await Future.delayed(Duration(seconds: 1));

  path = p.join(d.sandbox, 'myapp', path);
  touch(path);
}
