// 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.

import "dart:async";
import "dart:io";
import "package:test/test.dart";
import "package:package_config/packages.dart";
import "package:package_config/discovery.dart";
import "package:path/path.dart" as path;

const packagesFile = """
# A comment
foo=file:///dart/packages/foo/
bar=http://example.com/dart/packages/bar/
baz=packages/baz/
""";

void validatePackagesFile(Packages resolver, Uri location) {
  expect(resolver, isNotNull);
  expect(resolver.resolve(pkg("foo", "bar/baz")),
         equals(Uri.parse("file:///dart/packages/foo/bar/baz")));
  expect(resolver.resolve(pkg("bar", "baz/qux")),
         equals(Uri.parse("http://example.com/dart/packages/bar/baz/qux")));
  expect(resolver.resolve(pkg("baz", "qux/foo")),
         equals(location.resolve("packages/baz/qux/foo")));
  expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"]));
}

void validatePackagesDir(Packages resolver, Uri location) {
  // Expect three packages: foo, bar and baz
  expect(resolver, isNotNull);
  expect(resolver.resolve(pkg("foo", "bar/baz")),
         equals(location.resolve("packages/foo/bar/baz")));
  expect(resolver.resolve(pkg("bar", "baz/qux")),
         equals(location.resolve("packages/bar/baz/qux")));
  expect(resolver.resolve(pkg("baz", "qux/foo")),
         equals(location.resolve("packages/baz/qux/foo")));
  if (location.scheme == "file") {
    expect(resolver.packages, unorderedEquals(["foo", "bar", "baz"]));
  } else {
    expect(() => resolver.packages, throws);
  }
}


Uri pkg(String packageName, String packagePath) {
  var path;
  if (packagePath.startsWith('/')) {
    path = "$packageName$packagePath";
  } else {
    path = "$packageName/$packagePath";
  }
  return new Uri(scheme: "package", path: path);
}

main() {
  generalTest(".packages",
              {".packages": packagesFile,
               "script.dart": "main(){}",
               "packages": {"shouldNotBeFound": {}}},
              (Uri location) async {
    Packages resolver;
    resolver = await findPackages(location);
    validatePackagesFile(resolver, location);
    resolver = await findPackages(location.resolve("script.dart"));
    validatePackagesFile(resolver, location);
    var specificDiscovery = (location.scheme == "file")
        ? findPackagesFromFile
        : findPackagesFromNonFile;
    resolver = await specificDiscovery(location);
    validatePackagesFile(resolver, location);
    resolver = await specificDiscovery(location.resolve("script.dart"));
    validatePackagesFile(resolver, location);
  });

  generalTest("packages/",
              {"packages": { "foo": {}, "bar": {}, "baz": {}},
               "script.dart": "main(){}"},
              (Uri location) async {
    Packages resolver;
    bool isFile = (location.scheme == "file");
    resolver = await findPackages(location);
    validatePackagesDir(resolver, location);
    resolver = await findPackages(location.resolve("script.dart"));
    validatePackagesDir(resolver, location);
    var specificDiscovery = isFile
        ? findPackagesFromFile
        : findPackagesFromNonFile;
    resolver = await specificDiscovery(location);
    validatePackagesDir(resolver, location);
    resolver = await specificDiscovery(location.resolve("script.dart"));
    validatePackagesDir(resolver, location);
  });

  fileTest(".packages recursive",
           {".packages": packagesFile, "subdir": {"script.dart": "main(){}"}},
           (Uri location) async {
    Packages resolver;
    resolver = await findPackages(location.resolve("subdir/"));
    validatePackagesFile(resolver, location);
    resolver = await findPackages(location.resolve("subdir/script.dart"));
    validatePackagesFile(resolver, location);
    resolver = await findPackagesFromFile(location.resolve("subdir/"));
    validatePackagesFile(resolver, location);
    resolver =
        await findPackagesFromFile(location.resolve("subdir/script.dart"));
    validatePackagesFile(resolver, location);
  });

  httpTest(".packages not recursive",
           {".packages": packagesFile, "subdir": {"script.dart": "main(){}"}},
           (Uri location) async {
    Packages resolver;
    var subdir = location.resolve("subdir/");
    resolver = await findPackages(subdir);
    validatePackagesDir(resolver, subdir);
    resolver = await findPackages(subdir.resolve("script.dart"));
    validatePackagesDir(resolver, subdir);
    resolver = await findPackagesFromNonFile(subdir);
    validatePackagesDir(resolver, subdir);
    resolver = await findPackagesFromNonFile(subdir.resolve("script.dart"));
    validatePackagesDir(resolver, subdir);
  });

  fileTest("no packages",
          {"script.dart": "main(){}"},
          (Uri location) async {
    // A file: location with no .packages or packages returns
    // Packages.noPackages.
    Packages resolver;
    resolver = await findPackages(location);
    expect(resolver, same(Packages.noPackages));
    resolver = await findPackages(location.resolve("script.dart"));
    expect(resolver, same(Packages.noPackages));
    resolver = findPackagesFromFile(location);
    expect(resolver, same(Packages.noPackages));
    resolver = findPackagesFromFile(location.resolve("script.dart"));
    expect(resolver, same(Packages.noPackages));
  });

  httpTest("no packages",
           {"script.dart": "main(){}"},
           (Uri location) async {
    // A non-file: location with no .packages or packages/:
    // Assumes a packages dir exists, and resolves relative to that.
    Packages resolver;
    resolver = await findPackages(location);
    validatePackagesDir(resolver, location);
    resolver = await findPackages(location.resolve("script.dart"));
    validatePackagesDir(resolver, location);
    resolver = await findPackagesFromNonFile(location);
    validatePackagesDir(resolver, location);
    resolver = await findPackagesFromNonFile(location.resolve("script.dart"));
    validatePackagesDir(resolver, location);
  });

  test(".packages w/ loader", () async {
    Uri location = Uri.parse("krutch://example.com/path/");
    Future loader(Uri file) async {
      if (file.path.endsWith(".packages")) {
        return packagesFile.codeUnits;
      }
      throw "not found";
    }
    // A non-file: location with no .packages or packages/:
    // Assumes a packages dir exists, and resolves relative to that.
    Packages resolver;
    resolver = await findPackages(location, loader: loader);
    validatePackagesFile(resolver, location);
    resolver = await findPackages(location.resolve("script.dart"),
                                  loader: loader);
    validatePackagesFile(resolver, location);
    resolver = await findPackagesFromNonFile(location, loader: loader);
    validatePackagesFile(resolver, location);
    resolver = await findPackagesFromNonFile(location.resolve("script.dart"),
                                             loader: loader);
    validatePackagesFile(resolver, location);
  });

  test("no packages w/ loader", () async {
    Uri location = Uri.parse("krutch://example.com/path/");
    Future loader(Uri file) async {
      throw "not found";
    }
    // A non-file: location with no .packages or packages/:
    // Assumes a packages dir exists, and resolves relative to that.
    Packages resolver;
    resolver = await findPackages(location, loader: loader);
    validatePackagesDir(resolver, location);
    resolver = await findPackages(location.resolve("script.dart"),
                                  loader: loader);
    validatePackagesDir(resolver, location);
    resolver = await findPackagesFromNonFile(location, loader: loader);
    validatePackagesDir(resolver, location);
    resolver = await findPackagesFromNonFile(location.resolve("script.dart"),
                                             loader:loader);
    validatePackagesDir(resolver, location);
  });
}

/// Create a directory structure from [description] and run [fileTest].
///
/// Description is a map, each key is a file entry. If the value is a map,
/// it's a sub-dir, otherwise it's a file and the value is the content
/// as a string.
void fileTest(String name,
              Map description,
              Future fileTest(Uri directory)) {
  group("file-test", () {
    Directory tempDir = Directory.systemTemp.createTempSync("file-test");
    setUp(() {
      _createFiles(tempDir, description);
    });
    tearDown(() {
      tempDir.deleteSync(recursive: true);
    });
    test(name, () => fileTest(new Uri.directory(tempDir.path)));
  });
}

/// HTTP-server the directory structure from [description] and run [htpTest].
///
/// Description is a map, each key is a file entry. If the value is a map,
/// it's a sub-dir, otherwise it's a file and the value is the content
/// as a string.
void httpTest(String name, Map description, Future httpTest(Uri directory)) {
  group("http-test", () {
    var serverSub;
    var uri;
    setUp(() {
      return HttpServer
        .bind(InternetAddress.LOOPBACK_IP_V4, 0)
        .then((server) {
          uri = new Uri(scheme: "http",
                        host: "127.0.0.1",
                        port: server.port,
                        path: "/");
          serverSub = server.listen((HttpRequest request) {
            // No error handling.
            var path = request.uri.path;
            if (path.startsWith('/')) path = path.substring(1);
            if (path.endsWith('/')) path = path.substring(0, path.length - 1);
            var parts = path.split('/');
            var fileOrDir = description;
            for (int i = 0; i < parts.length; i++) {
              fileOrDir = fileOrDir[parts[i]];
              if (fileOrDir == null) {
                request.response.statusCode = 404;
                request.response.close();
              }
            }
            request.response.write(fileOrDir);
            request.response.close();
          });
        });
    });
    tearDown(() => serverSub.cancel());
    test(name, () => httpTest(uri));
  });
}

void generalTest(String name, Map description, Future action(Uri location)) {
  fileTest(name, description, action);
  httpTest(name, description, action);
}

void _createFiles(Directory target, Map description) {
  description.forEach((name, content) {
    if (content is Map) {
      Directory subDir = new Directory(path.join(target.path, name));
      subDir.createSync();
      _createFiles(subDir, content);
    } else {
      File file = new File(path.join(target.path, name));
      file.writeAsStringSync(content, flush: true);
    }
  });
}


