// 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/root_source.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;
Source rootSource;

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;
        rootSource = new RootSource(root);
        cache.register(rootSource);
      } 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);
    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();
  new Timer(0, (_) {
    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], rootSource);
  case 'versionless':
    return new Pair<String, Source>(match[1], versionlessSource);
  }
}
