// Copyright (c) 2014, 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.
//
// Test:
//   *) Compiling a script fetched over HTTP.
//   *) Importing a library fetched over HTTP.
//   *) Automatically resolving package_root when script is fetched over HTTP.

library http_launch_test;

import 'dart:async';
import 'dart:io';
import 'package:async_helper/async_helper.dart';
import 'package:expect/expect.dart';
import 'package:path/path.dart' as path;

Uri pathOfData = Platform.script.resolve('http_launch_data/');
Directory tempDir;
String outFilePath;

_sendNotFound(HttpResponse response) {
  response.statusCode = HttpStatus.NOT_FOUND;
  response.close();
}

Future handleRequest(HttpRequest request) {
  final String path = request.uri.path.substring(1);
  final Uri requestPath = pathOfData.resolve(path);
  final File file = new File(requestPath.toFilePath());
  return file.exists().then((bool found) {
    if (found) {
      file.openRead()
          .pipe(request.response)
          .catchError((e) { _sendNotFound(request.response); });
    } else {
      _sendNotFound(request.response);
    }
  });
}

Future launchDart2Js(args) {
  String ext = Platform.isWindows ? '.bat' : '';
  String command =
      path.normalize(path.join(path.fromUri(Platform.script),
                    '../../../../sdk/bin/dart2js${ext}'));
  return Process.run(command, args);
}

void check(ProcessResult result) {
  Expect.equals(0, result.exitCode);
  File outFile = new File(outFilePath);
  Expect.isTrue(outFile.existsSync());
  Expect.isTrue(outFile.readAsStringSync().contains("hello http tester"));
}

void checkNotFound(ProcessResult result, String filename) {
  Expect.notEquals(0, result.exitCode);
  File outFile = new File(outFilePath);
  Expect.isTrue(result.stdout.contains("404"));
  Expect.isTrue(result.stdout.contains(filename));
}

cleanup() {
  File outFile = new File(outFilePath);
  if (outFile.existsSync()) {
    outFile.deleteSync();
  }
}

Future testNonHttp() {
  String inFilePath = pathOfData.resolve('http_launch_main.dart').toFilePath();
  List<String> args = [inFilePath, "--out=" + outFilePath];
  return launchDart2Js(args)
      .then(check)
      .then((_) { cleanup(); });
}

Future testHttpMain(String serverUrl) {
  String inFilePath = '$serverUrl/http_launch_main.dart';
  List<String> args = [inFilePath, "--out=" + outFilePath];
  return launchDart2Js(args)
      .then(check)
      .then((_) { cleanup(); });
}

Future testHttpLib(String serverUrl) {
  File file = new File(path.join(tempDir.path, "in.dart"));
  file.writeAsStringSync("""
  import '$serverUrl/lib1.dart';
  main() { print(foo()); }
  """);
  String inFilePath = file.path;
  List<String> args = [inFilePath, "--out=" + outFilePath];
  return launchDart2Js(args)
      .then(check)
      .whenComplete(file.deleteSync)
      .then((_) { cleanup(); });
}

Future testHttpPackage(String serverUrl) {
  String inFilePath =
      pathOfData.resolve('http_launch_main_package.dart').toFilePath();
  String packageRoot = '$serverUrl/packages/';
  List<String> args = [inFilePath,
                       "--out=" + outFilePath,
                       "--package-root=" + packageRoot];
  return launchDart2Js(args)
      .then(check)
      .then((_) { cleanup(); });
}

Future testBadHttp(String serverUrl) {
  File file = new File(path.join(tempDir.path, "in_bad.dart"));
  file.writeAsStringSync("""
  import '$serverUrl/not_existing.dart';
  main() { print(foo()); }
  """);
  String inFilePath = file.path;
  List<String> args = [inFilePath, "--out=" + outFilePath];
  return launchDart2Js(args)
      .then((pr) => checkNotFound(pr, "not_existing.dart"))
      .whenComplete(file.deleteSync)
      .then((_) { cleanup(); });
}

Future testBadHttp2(String serverUrl) {
  String inFilePath = '$serverUrl/not_found.dart';
  List<String> args = [inFilePath, "--out=" + outFilePath];
  return launchDart2Js(args)
      .then((processResult) => checkNotFound(processResult, "not_found.dart"))
      .then((_) { cleanup(); });
}

serverRunning(HttpServer server, String scheme) {
  tempDir = Directory.systemTemp.createTempSync('directory_test');
  outFilePath = path.join(tempDir.path, "out.js");
  int port = server.port;
  String serverUrl = "$scheme://127.0.0.1:$port";

  asyncStart();
  server.listen(handleRequest);
  return new Future.value()
       .then((_) => cleanup())  // Make sure we start fresh.
       .then((_) => testNonHttp())
       .then((_) => testHttpMain(serverUrl))
       .then((_) => testHttpLib(serverUrl))
       .then((_) => testHttpPackage(serverUrl))
       .then((_) => testBadHttp(serverUrl))
       .then((_) => testBadHttp2(serverUrl))
       .whenComplete(() => tempDir.delete(recursive: true))
       .whenComplete(server.close)
       .then((_) => asyncEnd());
}

Future testHttp() {
  return HttpServer.bind(InternetAddress.LOOPBACK_IP_V4, 0)
      .then((HttpServer server) => serverRunning(server, "http"));
}

void initializeSSL() {
  Uri pathOfPkcert = pathOfData.resolve('pkcert');
  String testPkcertDatabase = pathOfPkcert.toFilePath();
  SecureSocket.initialize(database: testPkcertDatabase,
                          password: 'dartdart');
}

Future testHttps() {
  initializeSSL();
  return HttpServer.bindSecure(InternetAddress.LOOPBACK_IP_V4,
                               0,
                               certificateName: 'localhost_cert')
      .then((HttpServer server) => serverRunning(server, "https"));
}

main() {
  asyncStart();
  testHttp()
    .then((_) => testHttps)
    .whenComplete(asyncEnd);
}
