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

library shelf_proxy;

import 'dart:async';

import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:scheduled_test/scheduled_test.dart';
import 'package:shelf/shelf.dart' as shelf;
import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_proxy/shelf_proxy.dart';

/// The URI of the server the current proxy server is proxying to.
Uri targetUri;

/// The URI of the current proxy server.
Uri proxyUri;

void main() {
  group("forwarding", () {
    test("forwards request method", () {
      createProxy((request) {
        expect(request.method, equals('DELETE'));
        return new shelf.Response.ok(':)');
      });

      schedule(() => http.delete(proxyUri));
    });

    test("forwards request headers", () {
      createProxy((request) {
        expect(request.headers, containsPair('foo', 'bar'));
        expect(request.headers, containsPair('accept', '*/*'));
        return new shelf.Response.ok(':)');
      });

      get(headers: {
        'foo': 'bar',
        'accept': '*/*'
      });
    });

    test("forwards request body", () {
      createProxy((request) {
        expect(request.readAsString(), completion(equals('hello, server')));
        return new shelf.Response.ok(':)');
      });

      schedule(() => http.post(proxyUri, body: 'hello, server'));
    });

    test("forwards response status", () {
      createProxy((request) {
        return new shelf.Response(567);
      });

      expect(get().then((response) {
        expect(response.statusCode, equals(567));
      }), completes);
    });

    test("forwards response headers", () {
      createProxy((request) {
        return new shelf.Response.ok(':)', headers: {
          'foo': 'bar',
          'accept': '*/*'
        });
      });

      expect(get().then((response) {
        expect(response.headers, containsPair('foo', 'bar'));
        expect(response.headers, containsPair('accept', '*/*'));
      }), completes);
    });

    test("forwards response body", () {
      createProxy((request) {
        return new shelf.Response.ok('hello, client');
      });

      expect(schedule(() => http.read(proxyUri)),
          completion(equals('hello, client')));
    });

    test("adjusts the Host header for the target server", () {
      createProxy((request) {
        expect(request.headers, containsPair('host', targetUri.authority));
        return new shelf.Response.ok(':)');
      });

      get();
    });
  });

  group("via", () {
    test("adds a Via header to the request", () {
      createProxy((request) {
        expect(request.headers, containsPair('via', '1.1 shelf_proxy'));
        return new shelf.Response.ok(':)');
      });

      get();
    });

    test("adds to a request's existing Via header", () {
      createProxy((request) {
        expect(request.headers,
            containsPair('via', '1.0 something, 1.1 shelf_proxy'));
        return new shelf.Response.ok(':)');
      });

      get(headers: {'via': '1.0 something'});
    });

    test("adds a Via header to the response", () {
      createProxy((request) => new shelf.Response.ok(':)'));

      expect(get().then((response) {
        expect(response.headers, containsPair('via', '1.1 shelf_proxy'));
      }), completes);
    });

    test("adds to a response's existing Via header", () {
      createProxy((request) {
        return new shelf.Response.ok(':)', headers: {'via': '1.0 something'});
      });

      expect(get().then((response) {
        expect(response.headers,
            containsPair('via', '1.0 something, 1.1 shelf_proxy'));
      }), completes);
    });

    test("adds to a response's existing Via header", () {
      createProxy((request) {
        return new shelf.Response.ok(':)', headers: {'via': '1.0 something'});
      });

      expect(get().then((response) {
        expect(response.headers,
            containsPair('via', '1.0 something, 1.1 shelf_proxy'));
      }), completes);
    });
  });

  group("redirects", () {
    test("doesn't modify a Location for a foreign server", () {
      createProxy((request) {
        return new shelf.Response.found('http://dartlang.org');
      });

      expect(get().then((response) {
        expect(response.headers,
            containsPair('location', 'http://dartlang.org'));
      }), completes);
    });

    test("relativizes a reachable root-relative Location", () {
      createProxy((request) {
        return new shelf.Response.found('/foo/bar');
      }, targetPath: '/foo');

      expect(get().then((response) {
        expect(response.headers, containsPair('location', '/bar'));
      }), completes);
    });

    test("absolutizes an unreachable root-relative Location", () {
      createProxy((request) {
        return new shelf.Response.found('/baz');
      }, targetPath: '/foo');

      expect(get().then((response) {
        expect(response.headers,
            containsPair('location', targetUri.resolve('/baz').toString()));
      }), completes);
    });
  });

  test("removes a transfer-encoding header", () {
    var handler = mockHandler((request) {
      return new http.Response('', 200, headers: {
        'transfer-encoding': 'chunked'
      });
    });

    expect(handler(new shelf.Request('GET', Uri.parse('http://localhost/')))
        .then((response) {
      expect(response.headers, isNot(contains("transfer-encoding")));
    }), completes);
  });

  test("removes content-length and content-encoding for a gzipped response",
      () {
    var handler = mockHandler((request) {
      return new http.Response('', 200, headers: {
        'content-encoding': 'gzip',
        'content-length': '1234'
      });
    });

    expect(handler(new shelf.Request('GET', Uri.parse('http://localhost/')))
        .then((response) {
      expect(response.headers, isNot(contains("content-encoding")));
      expect(response.headers, isNot(contains("content-length")));
      expect(response.headers,
          containsPair('warning', '214 shelf_proxy "GZIP decoded"'));
    }), completes);
  });
}

/// Creates a proxy server proxying to a server running [handler].
///
/// [targetPath] is the root-relative path on the target server to proxy to. It
/// defaults to `/`.
void createProxy(shelf.Handler handler, {String targetPath}) {
  handler = wrapAsync(handler, 'target server handler');
  schedule(() {
    return shelf_io.serve(handler, 'localhost', 0).then((targetServer) {
      targetUri = Uri.parse('http://localhost:${targetServer.port}');
      if (targetPath != null) targetUri = targetUri.resolve(targetPath);
      var proxyServerHandler = wrapAsync(
          proxyHandler(targetUri), 'proxy server handler');

      return shelf_io.serve(proxyServerHandler, 'localhost', 0)
          .then((proxyServer) {
        proxyUri = Uri.parse('http://localhost:${proxyServer.port}');

        currentSchedule.onComplete.schedule(() {
          proxyServer.close(force: true);
          targetServer.close(force: true);
        }, 'tear down servers');
      });
    });
  }, 'spin up servers');
}

/// Creates a [shelf.Handler] that's backed by a [MockClient] running
/// [callback].
shelf.Handler mockHandler(callback(http.Request request)) {
  var client = new MockClient((request) {
    return new Future.sync(() => callback(request));
  });
  return proxyHandler('http://dartlang.org', client: client);
}

/// Schedules a GET request with [headers] to the proxy server.
Future<http.Response> get({Map<String, String> headers}) {
  return schedule(() {
    var uri = proxyUri;
    var request = new http.Request('GET', uri);
    if (headers != null) request.headers.addAll(headers);
    request.followRedirects = false;
    return request.send().then(http.Response.fromStream);
  }, 'GET proxy server');
}
