// Copyright (c) 2013, 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:crypto';
import 'dart:io';
import 'dart:isolate';
import 'dart:uri';
import 'dart:utf';

class Server {
  HttpServer server;
  bool passwordChanged = false;

  Future<Server> start() {
    var completer = new Completer();
    HttpServer.bind().then((s) {
      server = s;
      server.listen((HttpRequest request) {
        var response = request.response;
        if (request.uri.path == "/passwdchg") {
          passwordChanged = true;
          response.close();
          return;
        };

        String username;
        String password;
        if (request.uri.path == "/") {
          username = "username";
          password = "password";
        } else {
          username = request.uri.path.substring(1, 6);
          password = request.uri.path.substring(1, 6);
        }
        if (passwordChanged) password = "${password}1";
        if (request.headers[HttpHeaders.AUTHORIZATION] != null) {
          Expect.equals(1, request.headers[HttpHeaders.AUTHORIZATION].length);
          String authorization =
            request.headers[HttpHeaders.AUTHORIZATION][0];
          List<String> tokens = authorization.split(" ");
          Expect.equals("Basic", tokens[0]);
          String auth =
              CryptoUtils.bytesToBase64(encodeUtf8("$username:$password"));
          if (passwordChanged && auth != tokens[1]) {
            response.statusCode = HttpStatus.UNAUTHORIZED;
            response.headers.set(HttpHeaders.WWW_AUTHENTICATE,
                                 "Basic, realm=realm");
          } else {
            Expect.equals(auth, tokens[1]);
          }
        } else {
          response.statusCode = HttpStatus.UNAUTHORIZED;
          response.headers.set(HttpHeaders.WWW_AUTHENTICATE,
                               "Basic, realm=realm");
        }
        response.close();
      });
      completer.complete(this);
    });
    return completer.future;
  }

  void shutdown() {
    server.close();
  }

  int get port => server.port;
}

Future<Server> setupServer() {
  return new Server().start();
}

void testUrlUserInfo() {
  setupServer().then((server) {
    HttpClient client = new HttpClient();

    client.getUrl(Uri.parse(
        "http://username:password@127.0.0.1:${server.port}/"))
      .then((request) => request.close())
      .then((HttpClientResponse response) {
        response.listen((_) {}, onDone: () {
          server.shutdown();
          client.close();
        });
      });
  });
}

void testBasicNoCredentials() {
  setupServer().then((server) {
    HttpClient client = new HttpClient();

    Future makeRequest(Uri url) {
      return client.getUrl(url)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
          Expect.equals(HttpStatus.UNAUTHORIZED, response.statusCode);
          return response.reduce(null, (x, y) {});
        });
    }

    var futures = [];
    for (int i = 0; i < 5; i++) {
      futures.add(
          makeRequest(
              Uri.parse("http://127.0.0.1:${server.port}/test$i")));
      futures.add(
          makeRequest(
              Uri.parse(
                  "http://127.0.0.1:${server.port}/test$i/xxx")));
    }
    Future.wait(futures).then((_) {
      server.shutdown();
      client.close();
    });
  });
}

void testBasicCredentials() {
  setupServer().then((server) {
    HttpClient client = new HttpClient();

    Future makeRequest(Uri url) {
      return client.getUrl(url)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
          Expect.equals(HttpStatus.OK, response.statusCode);
          return response.reduce(null, (x, y) {});
        });
    }

    for (int i = 0; i < 5; i++) {
      client.addCredentials(
          Uri.parse("http://127.0.0.1:${server.port}/test$i"),
          "realm",
          new HttpClientBasicCredentials("test$i", "test$i"));
    }

    var futures = [];
    for (int i = 0; i < 5; i++) {
      futures.add(
          makeRequest(
              Uri.parse("http://127.0.0.1:${server.port}/test$i")));
      futures.add(
          makeRequest(
              Uri.parse(
                  "http://127.0.0.1:${server.port}/test$i/xxx")));
    }
    Future.wait(futures).then((_) {
      server.shutdown();
      client.close();
    });
  });
}

void testBasicAuthenticateCallback() {
  setupServer().then((server) {
    HttpClient client = new HttpClient();
    bool passwordChanged = false;

    client.authenticate = (Uri url, String scheme, String realm) {
      Expect.equals("Basic", scheme);
      Expect.equals("realm", realm);
      String username = url.path.substring(1, 6);
      String password = url.path.substring(1, 6);
      if (passwordChanged) password = "${password}1";
      Completer completer = new Completer();
      new Timer(const Duration(milliseconds: 10), () {
        client.addCredentials(
            url, realm, new HttpClientBasicCredentials(username, password));
        completer.complete(true);
      });
      return completer.future;
    };

    Future makeRequest(Uri url) {
      return client.getUrl(url)
        .then((HttpClientRequest request) => request.close())
        .then((HttpClientResponse response) {
          Expect.equals(HttpStatus.OK, response.statusCode);
          return response.reduce(null, (x, y) {});
        });
    }

    List<Future> makeRequests() {
      var futures = [];
      for (int i = 0; i < 5; i++) {
        futures.add(
            makeRequest(
                Uri.parse("http://127.0.0.1:${server.port}/test$i")));
        futures.add(
            makeRequest(
                Uri.parse("http://127.0.0.1:${server.port}/test$i/xxx")));
      }
      return futures;
    }

    Future.wait(makeRequests()).then((_) {
      makeRequest(
          Uri.parse("http://127.0.0.1:${server.port}/passwdchg")).then((_) {
        passwordChanged = true;
        Future.wait(makeRequests()).then((_) {
          server.shutdown();
          client.close();
        });
      });
    });
  });
}

void testLocalServerBasic() {
  HttpClient client = new HttpClient();

  client.authenticate = (Uri url, String scheme, String realm) {
    client.addCredentials(
        Uri.parse("http://127.0.0.1/basic"),
        "test",
        new HttpClientBasicCredentials("test", "test"));
    return new Future.immediate(true);
  };

  HttpClientConnection conn =
      client.getUrl(Uri.parse("http://127.0.0.1/basic/test"));
  conn.onResponse = (HttpClientResponse response) {
    Expect.equals(HttpStatus.OK, response.statusCode);
    response.inputStream.onData = () => response.inputStream.read();
    response.inputStream.onClosed = () {
      client.shutdown();
    };
  };
}

void testLocalServerDigest() {
  HttpClient client = new HttpClient();

  client.authenticate = (Uri url, String scheme, String realm) {
    print("url: $url, scheme: $scheme, realm: $realm");
    client.addCredentials(
        Uri.parse("http://127.0.0.1/digest"),
        "test",
        new HttpClientDigestCredentials("test", "test"));
    return new Future.immediate(true);
  };

  HttpClientConnection conn =
      client.getUrl(Uri.parse("http://127.0.0.1/digest/test"));
  conn.onResponse = (HttpClientResponse response) {
    Expect.equals(HttpStatus.OK, response.statusCode);
    response.inputStream.onData = () => response.inputStream.read();
    response.inputStream.onClosed = () {
      client.shutdown();
    };
  };
}

main() {
  testUrlUserInfo();
  testBasicNoCredentials();
  testBasicCredentials();
  testBasicAuthenticateCallback();
  // These teste are not normally run. They can be used for locally
  // testing with another web server (e.g. Apache).
  //testLocalServerBasic();
  //testLocalServerDigest();
}
