// 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 "package:convert/convert.dart";
import "package:crypto/crypto.dart";
import "package:http_io/http_io.dart";
import "package:test/test.dart";

class Server {
  HttpServer server;
  int unauthCount = 0; // Counter of the 401 responses.
  int successCount = 0; // Counter of the successful responses.
  int nonceCount = 0; // Counter of use of current nonce.
  String ha1;

  static Future<Server> start(String algorithm, String qop,
      {int nonceStaleAfter, bool useNextNonce: false}) {
    return new Server()._start(algorithm, qop, nonceStaleAfter, useNextNonce);
  }

  Future<Server> _start(String serverAlgorithm, String serverQop,
      int nonceStaleAfter, bool useNextNonce) {
    Set ncs = new Set();
    // Calculate ha1.
    String realm = "test";
    String username = "dart";
    String password = "password";
    var hasher = md5.convert("$username:$realm:$password".codeUnits);
    ha1 = hex.encode(hasher.bytes);

    var nonce = "12345678"; // No need for random nonce in test.

    var completer = new Completer<Server>();
    HttpServer.bind("127.0.0.1", 0).then((s) {
      server = s;
      server.listen((HttpRequest request) {
        sendUnauthorizedResponse(HttpResponse response, {stale: false}) {
          response.statusCode = HttpStatus.UNAUTHORIZED;
          StringBuffer authHeader = new StringBuffer();
          authHeader.write('Digest');
          authHeader.write(', realm="$realm"');
          authHeader.write(', nonce="$nonce"');
          if (stale) authHeader.write(', stale="true"');
          if (serverAlgorithm != null) {
            authHeader.write(', algorithm=$serverAlgorithm');
          }
          authHeader.write(', domain="/digest/"');
          if (serverQop != null) authHeader.write(', qop="$serverQop"');
          response.headers.set(HttpHeaders.WWW_AUTHENTICATE, authHeader);
          unauthCount++;
        }

        var response = request.response;
        if (request.headers[HttpHeaders.AUTHORIZATION] != null) {
          expect(1, equals(request.headers[HttpHeaders.AUTHORIZATION].length));
          String authorization = request.headers[HttpHeaders.AUTHORIZATION][0];
          HeaderValue header =
              HeaderValue.parse(authorization, parameterSeparator: ",");
          if (header.value.toLowerCase() == "basic") {
            sendUnauthorizedResponse(response);
          } else if (!useNextNonce && nonceCount == nonceStaleAfter) {
            nonce = "87654321";
            nonceCount = 0;
            sendUnauthorizedResponse(response, stale: true);
          } else {
            var uri = header.parameters["uri"];
            var qop = header.parameters["qop"];
            var cnonce = header.parameters["cnonce"];
            var nc = header.parameters["nc"];
            expect("digest", equals(header.value.toLowerCase()));
            expect("dart", equals(header.parameters["username"]));
            expect(realm, equals(header.parameters["realm"]));
            expect("MD5", equals(header.parameters["algorithm"]));
            expect(nonce, equals(header.parameters["nonce"]));
            expect(request.uri.toString(), equals(uri));
            if (qop != null) {
              // A server qop of auth-int is downgraded to none by the client.
              expect("auth", equals(serverQop));
              expect("auth", equals(header.parameters["qop"]));
              expect(cnonce, isNotNull);
              expect(nc, isNotNull);
              expect(ncs.contains(nc), isFalse);
              ncs.add(nc);
            } else {
              expect(cnonce, isNull);
              expect(nc, isNull);
            }
            expect(header.parameters["response"], isNotNull);

            var hasher = md5.convert("${request.method}:$uri".codeUnits);
            var ha2 = hex.encode(hasher.bytes);

            Digest digest;
            if (qop == null || qop == "" || qop == "none") {
              digest = md5.convert("$ha1:$nonce:$ha2".codeUnits);
            } else {
              digest =
                  md5.convert("$ha1:$nonce:$nc:$cnonce:$qop:$ha2".codeUnits);
            }
            expect(hex.encode(digest.bytes),
                equals(header.parameters["response"]));

            successCount++;
            nonceCount++;

            // Add a bogus Authentication-Info for testing.
            var info = 'rspauth="77180d1ab3d6c9de084766977790f482", '
                'cnonce="8f971178", '
                'nc=000002c74, '
                'qop=auth';
            if (useNextNonce && nonceCount == nonceStaleAfter) {
              nonce = "abcdef01";
              info += ', nextnonce="$nonce"';
            }
            response.headers.set("Authentication-Info", info);
          }
        } else {
          sendUnauthorizedResponse(response);
        }
        response.close();
      });
      completer.complete(this);
    });
    return completer.future;
  }

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

  int get port => server.port;
}

Future<Null> testNoCredentials(String algorithm, String qop) {
  Completer<Null> completer = new Completer();
  Server.start(algorithm, qop).then((server) {
    HttpClient client = new HttpClient();

    // Add digest credentials which does not match the path requested.
    client.addCredentials(Uri.parse("http://127.0.0.1:${server.port}/xxx"),
        "test", new HttpClientDigestCredentials("dart", "password"));

    // Add basic credentials for the path requested.
    client.addCredentials(Uri.parse("http://127.0.0.1:${server.port}/digest"),
        "test", new HttpClientBasicCredentials("dart", "password"));

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

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

Future<Null> testCredentials(String algorithm, String qop) {
  Completer<Null> completer = new Completer();
  Server.start(algorithm, qop).then((server) {
    HttpClient client = new HttpClient();

    Future makeRequest(Uri url) {
      return client
          .getUrl(url)
          .then((HttpClientRequest request) => request.close())
          .then((HttpClientResponse response) {
        expect(HttpStatus.OK, equals(response.statusCode));
        expect(1, equals(response.headers["Authentication-Info"].length));
        return response.fold(null, (x, y) {});
      });
    }

    client.addCredentials(Uri.parse("http://127.0.0.1:${server.port}/digest"),
        "test", new HttpClientDigestCredentials("dart", "password"));

    var futures = <Future>[];
    for (int i = 0; i < 2; i++) {
      String uriBase = "http://127.0.0.1:${server.port}/digest";
      futures.add(makeRequest(Uri.parse(uriBase)));
      futures.add(makeRequest(Uri.parse("$uriBase?querystring")));
      futures.add(makeRequest(Uri.parse("$uriBase?querystring#fragment")));
    }
    Future.wait(futures).then((_) {
      server.shutdown();
      client.close();
      completer.complete(null);
    });
  });
  return completer.future;
}

Future<Null> testAuthenticateCallback(String algorithm, String qop) {
  Completer<Null> completer = new Completer();
  Server.start(algorithm, qop).then((server) {
    HttpClient client = new HttpClient();

    client.authenticate = (Uri url, String scheme, String realm) {
      expect("Digest", equals(scheme));
      expect("test", equals(realm));
      Completer<bool> completer = new Completer<bool>();
      new Timer(const Duration(milliseconds: 10), () {
        client.addCredentials(
            Uri.parse("http://127.0.0.1:${server.port}/digest"),
            "test",
            new HttpClientDigestCredentials("dart", "password"));
        completer.complete(true);
      });
      return completer.future;
    };

    Future makeRequest(Uri url) {
      return client
          .getUrl(url)
          .then((HttpClientRequest request) => request.close())
          .then((HttpClientResponse response) {
        expect(HttpStatus.OK, equals(response.statusCode));
        expect(1, equals(response.headers["Authentication-Info"].length));
        return response.fold(null, (x, y) {});
      });
    }

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

Future<Null> testStaleNonce() {
  Completer<Null> completer = new Completer();
  Server.start("MD5", "auth", nonceStaleAfter: 2).then((server) {
    HttpClient client = new HttpClient();

    Future makeRequest(Uri url) {
      return client
          .getUrl(url)
          .then((HttpClientRequest request) => request.close())
          .then((HttpClientResponse response) {
        expect(HttpStatus.OK, equals(response.statusCode));
        expect(1, equals(response.headers["Authentication-Info"].length));
        return response.fold(null, (x, y) {});
      });
    }

    Uri uri = Uri.parse("http://127.0.0.1:${server.port}/digest");
    var credentials = new HttpClientDigestCredentials("dart", "password");
    client.addCredentials(uri, "test", credentials);

    makeRequest(uri)
        .then((_) => makeRequest(uri))
        .then((_) => makeRequest(uri))
        .then((_) => makeRequest(uri))
        .then((_) {
      expect(2, equals(server.unauthCount));
      expect(4, equals(server.successCount));
      server.shutdown();
      client.close();
      completer.complete(null);
    });
  });
  return completer.future;
}

Future<Null> testNextNonce() {
  Completer<Null> completer = new Completer();
  Server.start("MD5", "auth", nonceStaleAfter: 2, useNextNonce: true)
      .then((server) {
    HttpClient client = new HttpClient();

    Future makeRequest(Uri url) {
      return client
          .getUrl(url)
          .then((HttpClientRequest request) => request.close())
          .then((HttpClientResponse response) {
        expect(HttpStatus.OK, equals(response.statusCode));
        expect(1, equals(response.headers["Authentication-Info"].length));
        return response.fold(null, (x, y) {});
      });
    }

    Uri uri = Uri.parse("http://127.0.0.1:${server.port}/digest");
    var credentials = new HttpClientDigestCredentials("dart", "password");
    client.addCredentials(uri, "test", credentials);

    makeRequest(uri)
        .then((_) => makeRequest(uri))
        .then((_) => makeRequest(uri))
        .then((_) => makeRequest(uri))
        .then((_) {
      expect(1, equals(server.unauthCount));
      expect(4, equals(server.successCount));
      server.shutdown();
      client.close();
      completer.complete(null);
    });
  });
  return completer.future;
}

main() {
  test("NoCredentials", () async {
    await testNoCredentials(null, null);
  });
  test("NoCredentials MD5", () async {
    await testNoCredentials("MD5", null);
  });
  test("NoCredentials MD5 auth", () async {
    await testNoCredentials("MD5", "auth");
  });
  test("Credentials", () async {
    await testCredentials(null, null);
  });
  test("Credentials MD5", () async {
    await testCredentials("MD5", null);
  });
  test("Credentials MD5 auth", () async {
    await testCredentials("MD5", "auth");
  });
  test("Credentials MD5 auth-int", () async {
    await testCredentials("MD5", "auth-int");
  });
  test("AuthenticateCallback", () async {
    await testAuthenticateCallback(null, null);
  });
  test("AuthenticateCallback MD5", () async {
    await testAuthenticateCallback("MD5", null);
  });
  test("AuthenticateCallback MD5 auth", () async {
    await testAuthenticateCallback("MD5", "auth");
  });
  test("AuthenticateCallback MD5 auth-int", () async {
    await testAuthenticateCallback("MD5", "auth-int");
  });
  test("StaleNonce", () async {
    await testStaleNonce();
  });
  test("NextNonce", () async {
    await testNextNonce();
  });
}
