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

library pub_update_test;

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

import '../../pub/lock_file.dart';
import '../../pub/package.dart';
import '../../pub/pubspec.dart';
import '../../pub/source.dart';
import '../../pub/source_registry.dart';
import '../../pub/system_cache.dart';
import '../../pub/utils.dart';
import '../../pub/version.dart';
import '../../pub/version_solver.dart';
import '../../../pkg/unittest/lib/unittest.dart';

Matcher noVersion(List<String> packages) {
  return predicate((x) {
    if (x is! NoVersionException) return false;

    // Make sure the error string mentions the conflicting dependers.
    var message = x.toString();
    return packages.every((package) => message.contains(package));
  }, "is a NoVersionException");
}

Matcher disjointConstraint(List<String> packages) {
  return predicate((x) {
    if (x is! DisjointConstraintException) return false;

    // Make sure the error string mentions the conflicting dependers.
    var message = x.toString();
    return packages.every((package) => message.contains(package));
  }, "is a DisjointConstraintException");
}

Matcher descriptionMismatch(String package1, String package2) {
  return predicate((x) {
    if (x is! DescriptionMismatchException) return false;

    // Make sure the error string mentions the conflicting dependers.
    if (!x.toString().contains(package1)) return false;
    if (!x.toString().contains(package2)) return false;

    return true;
  }, "is a DescriptionMismatchException");
}

final couldNotSolve = predicate((x) => x is CouldNotSolveException,
    "is a CouldNotSolveException");

Matcher sourceMismatch(String package1, String package2) {
  return predicate((x) {
    if (x is! SourceMismatchException) return false;

    // Make sure the error string mentions the conflicting dependers.
    if (!x.toString().contains(package1)) return false;
    if (!x.toString().contains(package2)) return false;

    return true;
  }, "is a SourceMismatchException");
}

MockSource source1;
MockSource source2;
Source versionlessSource;

main() {
  testResolve('no dependencies', {
    'myapp 0.0.0': {}
  }, result: {
    'myapp from root': '0.0.0'
  });

  testResolve('simple dependency tree', {
    'myapp 0.0.0': {
      'a': '1.0.0',
      'b': '1.0.0'
    },
    'a 1.0.0': {
      'aa': '1.0.0',
      'ab': '1.0.0'
    },
    'aa 1.0.0': {},
    'ab 1.0.0': {},
    'b 1.0.0': {
      'ba': '1.0.0',
      'bb': '1.0.0'
    },
    'ba 1.0.0': {},
    'bb 1.0.0': {}
  }, result: {
    'myapp from root': '0.0.0',
    'a': '1.0.0',
    'aa': '1.0.0',
    'ab': '1.0.0',
    'b': '1.0.0',
    'ba': '1.0.0',
    'bb': '1.0.0'
  });

  testResolve('shared dependency with overlapping constraints', {
    'myapp 0.0.0': {
      'a': '1.0.0',
      'b': '1.0.0'
    },
    'a 1.0.0': {
      'shared': '>=2.0.0 <4.0.0'
    },
    'b 1.0.0': {
      'shared': '>=3.0.0 <5.0.0'
    },
    'shared 2.0.0': {},
    'shared 3.0.0': {},
    'shared 3.6.9': {},
    'shared 4.0.0': {},
    'shared 5.0.0': {},
  }, result: {
    'myapp from root': '0.0.0',
    'a': '1.0.0',
    'b': '1.0.0',
    'shared': '3.6.9'
  });

  testResolve('shared dependency where dependent version in turn affects '
              'other dependencies', {
    'myapp 0.0.0': {
      'foo': '<=1.0.2',
      'bar': '1.0.0'
    },
    'foo 1.0.0': {},
    'foo 1.0.1': { 'bang': '1.0.0' },
    'foo 1.0.2': { 'whoop': '1.0.0' },
    'foo 1.0.3': { 'zoop': '1.0.0' },
    'bar 1.0.0': { 'foo': '<=1.0.1' },
    'bang 1.0.0': {},
    'whoop 1.0.0': {},
    'zoop 1.0.0': {}
  }, result: {
    'myapp from root': '0.0.0',
    'foo': '1.0.1',
    'bar': '1.0.0',
    'bang': '1.0.0'
  });

  testResolve('from versionless source', {
    'myapp 0.0.0': {
      'foo from versionless': 'any'
    },
    'foo 1.2.3 from versionless': {}
  }, result: {
    'myapp from root': '0.0.0',
    'foo from versionless': '1.2.3'
  });

  testResolve('transitively through versionless source', {
    'myapp 0.0.0': {
      'foo from versionless': 'any'
    },
    'foo 1.2.3 from versionless': {
      'bar': '>=1.0.0'
    },
    'bar 1.1.0': {}
  }, result: {
    'myapp from root': '0.0.0',
    'foo from versionless': '1.2.3',
    'bar': '1.1.0'
  });

  testResolve('with compatible locked dependency', {
    'myapp 0.0.0': {
      'foo': 'any'
    },
    'foo 1.0.0': { 'bar': '1.0.0' },
    'foo 1.0.1': { 'bar': '1.0.1' },
    'foo 1.0.2': { 'bar': '1.0.2' },
    'bar 1.0.0': {},
    'bar 1.0.1': {},
    'bar 1.0.2': {}
  }, lockfile: {
    'foo': '1.0.1'
  }, result: {
    'myapp from root': '0.0.0',
    'foo': '1.0.1',
    'bar': '1.0.1'
  });

  testResolve('with incompatible locked dependency', {
    'myapp 0.0.0': {
      'foo': '>1.0.1'
    },
    'foo 1.0.0': { 'bar': '1.0.0' },
    'foo 1.0.1': { 'bar': '1.0.1' },
    'foo 1.0.2': { 'bar': '1.0.2' },
    'bar 1.0.0': {},
    'bar 1.0.1': {},
    'bar 1.0.2': {}
  }, lockfile: {
    'foo': '1.0.1'
  }, result: {
    'myapp from root': '0.0.0',
    'foo': '1.0.2',
    'bar': '1.0.2'
  });

  testResolve('with unrelated locked dependency', {
    'myapp 0.0.0': {
      'foo': 'any'
    },
    'foo 1.0.0': { 'bar': '1.0.0' },
    'foo 1.0.1': { 'bar': '1.0.1' },
    'foo 1.0.2': { 'bar': '1.0.2' },
    'bar 1.0.0': {},
    'bar 1.0.1': {},
    'bar 1.0.2': {},
    'baz 1.0.0': {}
  }, lockfile: {
    'baz': '1.0.0'
  }, result: {
    'myapp from root': '0.0.0',
    'foo': '1.0.2',
    'bar': '1.0.2'
  });

  testResolve('circular dependency', {
    'myapp 1.0.0': {
      'foo': '1.0.0'
    },
    'foo 1.0.0': {
      'bar': '1.0.0'
    },
    'bar 1.0.0': {
      'foo': '1.0.0'
    }
  }, result: {
    'myapp from root': '1.0.0',
    'foo': '1.0.0',
    'bar': '1.0.0'
  });

  testResolve('dependency back onto root package', {
    'myapp 1.0.0': {
      'foo': '1.0.0'
    },
    'foo 1.0.0': {
      'myapp from root': '>=1.0.0'
    }
  }, result: {
    'myapp from root': '1.0.0',
    'foo': '1.0.0'
  });

  testResolve('dependency back onto root package with different source', {
    'myapp 1.0.0': {
      'foo': '1.0.0'
    },
    'foo 1.0.0': {
      'myapp': '>=1.0.0'
    }
  }, result: {
    'myapp from root': '1.0.0',
    'foo': '1.0.0'
  });

  testResolve('mismatched dependencies back onto root package', {
    'myapp 1.0.0': {
      'foo': '1.0.0',
      'bar': '1.0.0'
    },
    'foo 1.0.0': {
      'myapp': '>=1.0.0'
    },
    'bar 1.0.0': {
      'myapp from mock2': '>=1.0.0'
    }
  }, error: sourceMismatch('foo', 'bar'));

  testResolve('dependency back onto root package with wrong version', {
    'myapp 1.0.0': {
      'foo': '1.0.0'
    },
    'foo 1.0.0': {
      'myapp': '<1.0.0'
    }
  }, error: disjointConstraint(['foo']));

  testResolve('no version that matches requirement', {
    'myapp 0.0.0': {
      'foo': '>=1.0.0 <2.0.0'
    },
    'foo 2.0.0': {},
    'foo 2.1.3': {}
  }, error: noVersion(['myapp']));

  testResolve('no version that matches combined constraint', {
    'myapp 0.0.0': {
      'foo': '1.0.0',
      'bar': '1.0.0'
    },
    'foo 1.0.0': {
      'shared': '>=2.0.0 <3.0.0'
    },
    'bar 1.0.0': {
      'shared': '>=2.9.0 <4.0.0'
    },
    'shared 2.5.0': {},
    'shared 3.5.0': {}
  }, error: noVersion(['foo', 'bar']));

  testResolve('disjoint constraints', {
    'myapp 0.0.0': {
      'foo': '1.0.0',
      'bar': '1.0.0'
    },
    'foo 1.0.0': {
      'shared': '<=2.0.0'
    },
    'bar 1.0.0': {
      'shared': '>3.0.0'
    },
    'shared 2.0.0': {},
    'shared 4.0.0': {}
  }, error: disjointConstraint(['foo', 'bar']));

  testResolve('mismatched descriptions', {
    'myapp 0.0.0': {
      'foo': '1.0.0',
      'bar': '1.0.0'
    },
    'foo 1.0.0': {
      'shared-x': '1.0.0'
    },
    'bar 1.0.0': {
      'shared-y': '1.0.0'
    },
    'shared-x 1.0.0': {},
    'shared-y 1.0.0': {}
  }, error: descriptionMismatch('foo', 'bar'));

  testResolve('mismatched sources', {
    'myapp 0.0.0': {
      'foo': '1.0.0',
      'bar': '1.0.0'
    },
    'foo 1.0.0': {
      'shared': '1.0.0'
    },
    'bar 1.0.0': {
      'shared from mock2': '1.0.0'
    },
    'shared 1.0.0': {},
    'shared 1.0.0 from mock2': {}
  }, error: sourceMismatch('foo', 'bar'));

  testResolve('unstable dependency graph', {
    'myapp 0.0.0': {
      'a': '>=1.0.0'
    },
    'a 1.0.0': {},
    'a 2.0.0': {
      'b': '1.0.0'
    },
    'b 1.0.0': {
      'a': '1.0.0'
    }
  }, error: couldNotSolve);

// TODO(rnystrom): More stuff to test:
// - Depending on a non-existent package.
// - Test that only a certain number requests are sent to the mock source so we
//   can keep track of server traffic.
}

testResolve(description, packages, {lockfile, result, Matcher error}) {
  test(description, () {
    var cache = new SystemCache('.');
    source1 = new MockSource('mock1');
    source2 = new MockSource('mock2');
    versionlessSource = new MockVersionlessSource();
    cache.register(source1);
    cache.register(source2);
    cache.register(versionlessSource);
    cache.sources.setDefault(source1.name);

    // Build the test package graph.
    var root;
    packages.forEach((nameVersion, dependencies) {
      var parsed = parseSource(nameVersion);
      nameVersion = parsed.first;
      var source = parsed.last;

      var parts = nameVersion.split(' ');
      var name = parts[0];
      var version = parts[1];

      var package = source1.mockPackage(name, version, dependencies);
      if (name == 'myapp') {
        // Don't add the root package to the server, so we can verify that Pub
        // doesn't try to look up information about the local package on the
        // remote server.
        root = package;
      } else {
        source.addPackage(package);
      }
    });

    // Clean up the expectation.
    if (result != null) {
      var newResult = {};
      result.forEach((name, version) {
        var parsed = parseSource(name);
        name = parsed.first;
        var source = parsed.last;
        version = new Version.parse(version);
        newResult[name] = new PackageId(name, source, version, name);
      });
      result = newResult;
    }

    var realLockFile = new LockFile.empty();
    if (lockfile != null) {
      lockfile.forEach((name, version) {
        version = new Version.parse(version);
        realLockFile.packages[name] =
          new PackageId(name, source1, version, name);
      });
    }

    // Resolve the versions.
    var future = resolveVersions(cache.sources, root, realLockFile);

    if (result != null) {
      expect(future, completion(predicate((actualResult) {
        for (var actualId in actualResult) {
          if (!result.containsKey(actualId.name)) return false;
          var expectedId = result.remove(actualId.name);
          if (actualId != expectedId) return false;
        }
        return result.isEmpty;
      }, 'packages to match $result')));
    } else if (error != null) {
      expect(future, throwsA(error));
    }
  });
}

/// A source used for testing. This both creates mock package objects and acts
/// as a source for them.
///
/// In order to support testing packages that have the same name but different
/// descriptions, a package's name is calculated by taking the description
/// string and stripping off any trailing hyphen followed by non-hyphen
/// characters.
class MockSource extends Source {
  final Map<String, Map<Version, Package>> _packages;

  final String name;
  bool get shouldCache => true;

  MockSource(this.name)
      : _packages = <String, Map<Version, Package>>{};

  Future<List<Version>> getVersions(String name, String description) {
    return fakeAsync(() => _packages[description].keys.toList());
  }

  Future<Pubspec> describe(PackageId id) {
    return fakeAsync(() {
      return _packages[id.name][id.version].pubspec;
    });
  }

  Future<bool> install(PackageId id, String path) {
    throw 'no';
  }

  Package mockPackage(String description, String version,
      Map dependencyStrings) {
    // Build the pubspec dependencies.
    var dependencies = <PackageRef>[];
    dependencyStrings.forEach((name, constraint) {
      var parsed = parseSource(name);
      var description = parsed.first;
      var packageName = description.replaceFirst(new RegExp(r"-[^-]+$"), "");
      dependencies.add(new PackageRef(packageName, parsed.last,
          new VersionConstraint.parse(constraint), description));
    });

    var pubspec = new Pubspec(
        description, new Version.parse(version), dependencies,
        new PubspecEnvironment());
    return new Package.inMemory(pubspec);
  }

  void addPackage(Package package) {
    _packages.putIfAbsent(package.name, () => new Map<Version, Package>());
    _packages[package.name][package.version] = package;
  }
}

/// A source used for testing that doesn't natively understand versioning,
/// similar to how the Git and SDK sources work.
class MockVersionlessSource extends Source {
  final Map<String, Package> _packages;

  final String name = 'versionless';
  final bool shouldCache = false;

  MockVersionlessSource()
    : _packages = <String, Package>{};

  Future<bool> install(PackageId id, String path) {
    throw 'no';
  }

  Future<Pubspec> describe(PackageId id) {
    return new Future<Pubspec>.immediate(_packages[id.description].pubspec);
  }

  void addPackage(Package package) {
    _packages[package.name] = package;
  }
}

Future fakeAsync(callback()) {
  var completer = new Completer();
  Timer.run(() {
    completer.complete(callback());
  });

  return completer.future;
}

Pair<String, Source> parseSource(String name) {
  var match = new RegExp(r"(.*) from (.*)").firstMatch(name);
  if (match == null) return new Pair<String, Source>(name, source1);
  switch (match[2]) {
  case 'mock1': return new Pair<String, Source>(match[1], source1);
  case 'mock2': return new Pair<String, Source>(match[1], source2);
  case 'root': return new Pair<String, Source>(match[1], null);
  case 'versionless':
    return new Pair<String, Source>(match[1], versionlessSource);
  }
}
