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

import '../launch_helper.dart' show launchDart2Js;

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);
    }
  });
}

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);
}
