// Copyright (c) 2017, 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.

/// @assertion String findProxyFromEnvironment(
///  Uri url, {
///  Map<String, String> environment
///  })
/// Function for resolving the proxy server to be used for an HTTP connection from
/// the proxy configuration specified through environment variables.
///
/// The following environment variables are taken into account:
///
/// http_proxy
/// https_proxy
/// no_proxy
/// HTTP_PROXY
/// HTTPS_PROXY
/// NO_PROXY
/// http_proxy and HTTP_PROXY specify the proxy server to use for http:// urls.
/// Use the format hostname:port. If no port is used a default of 1080 will be
/// used. If both are set the lower case one takes precedence.
///
/// https_proxy and HTTPS_PROXY specify the proxy server to use for https://
/// urls. Use the format hostname:port. If no port is used a default of 1080 will
/// be used. If both are set the lower case one takes precedence.
///
/// no_proxy and NO_PROXY specify a comma separated list of postfixes of
/// hostnames for which not to use the proxy server. E.g. the value
/// "localhost,127.0.0.1" will make requests to both "localhost" and "127.0.0.1"
/// not use a proxy. If both are set the lower case one takes precedence.
///
/// To activate this way of resolving proxies assign this function to the
/// findProxy property on the HttpClient.
///
/// HttpClient client = new HttpClient();
/// client.findProxy = HttpClient.findProxyFromEnvironment;
/// If you don't want to use the system environment you can use a different one
/// by wrapping the function.
///
/// HttpClient client = new HttpClient();
/// client.findProxy = (url) {
///   return HttpClient.findProxyFromEnvironment(
///     url, {"http_proxy": ..., "no_proxy": ...});
///   }
/// If a proxy requires authentication it is possible to configure the username
/// and password as well. Use the format username:password@hostname:port to
/// include the username and password. Alternatively the API addProxyCredentials
/// can be used to set credentials for proxies which require authentication.
///
/// @description Checks that if both http_proxy and HTTP_PROXY specified then
/// http_proxy takes precedence
/// @author sgrekhov@unipro.ru

import "dart:io";
import "dart:convert";
import "../../../Utils/expect.dart";

var localhost = InternetAddress.loopbackIPv4.address;

test() async {
  bool findProxyCalled = false;
  String hello = "Hello world!";
  HttpServer server = await HttpServer.bind(localhost, 0);
  server.listen((HttpRequest request) {
    Expect.fail("No request expected");
  });

  HttpServer proxyServer = await HttpServer.bind(localhost, 0);
  proxyServer.listen((HttpRequest request) {
    Expect.isTrue(findProxyCalled);
    request.response.close();
    proxyServer.close();
    server.close();
    asyncEnd();
  });

  HttpClient client = new HttpClient();
  client.findProxy = (Uri url) {
    findProxyCalled = true;
    return HttpClient.findProxyFromEnvironment(url,
        environment: {
          "http_proxy": localhost + ":${proxyServer.port}",
          "HTTP_PROXY": localhost + ":${server.port}"
        });
  };

  client.get(localhost, server.port, "")
      .then((HttpClientRequest request) => request.close())
      .then((HttpClientResponse response) {
    response.cast<List<int>>().transform(utf8.decoder).listen((content) {
      Expect.equals(hello, content);
    });
  });
}

main() {
  asyncStart();
  test();
}
