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

import 'dart:async';

import 'package:shelf/shelf.dart';
import 'package:test/test.dart';

import 'test_util.dart';

void main() {
  test('forwards the request and response if both handlers are null', () {
    var handler = const Pipeline()
        .addMiddleware(createMiddleware())
        .addHandler((request) {
      return syncHandler(request, headers: {'from': 'innerHandler'});
    });

    return makeSimpleRequest(handler).then((response) {
      expect(response.headers['from'], 'innerHandler');
    });
  });

  group('requestHandler', () {
    test('sync null response forwards to inner handler', () {
      var handler = const Pipeline()
          .addMiddleware(createMiddleware(requestHandler: (request) => null))
          .addHandler(syncHandler);

      return makeSimpleRequest(handler).then((response) {
        expect(response.headers['from'], isNull);
      });
    });

    test('async null response forwards to inner handler', () {
      var handler = const Pipeline()
          .addMiddleware(createMiddleware(
              requestHandler: (request) => new Future.value(null)))
          .addHandler(syncHandler);

      return makeSimpleRequest(handler).then((response) {
        expect(response.headers['from'], isNull);
      });
    });

    test('sync response is returned', () {
      var handler = const Pipeline()
          .addMiddleware(createMiddleware(
              requestHandler: (request) => _middlewareResponse))
          .addHandler(_failHandler);

      return makeSimpleRequest(handler).then((response) {
        expect(response.headers['from'], 'middleware');
      });
    });

    test('async response is returned', () {
      var handler = const Pipeline()
          .addMiddleware(createMiddleware(
              requestHandler: (request) =>
                  new Future.value(_middlewareResponse)))
          .addHandler(_failHandler);

      return makeSimpleRequest(handler).then((response) {
        expect(response.headers['from'], 'middleware');
      });
    });

    group('with responseHandler', () {
      test('with sync result, responseHandler is not called', () {
        var middleware = createMiddleware(
            requestHandler: (request) => _middlewareResponse,
            responseHandler: (response) => fail('should not be called'));

        var handler =
            const Pipeline().addMiddleware(middleware).addHandler(syncHandler);

        return makeSimpleRequest(handler).then((response) {
          expect(response.headers['from'], 'middleware');
        });
      });

      test('with async result, responseHandler is not called', () {
        var middleware = createMiddleware(
            requestHandler: (request) => new Future.value(_middlewareResponse),
            responseHandler: (response) => fail('should not be called'));
        var handler =
            const Pipeline().addMiddleware(middleware).addHandler(syncHandler);

        return makeSimpleRequest(handler).then((response) {
          expect(response.headers['from'], 'middleware');
        });
      });
    });
  });

  group('responseHandler', () {
    test('innerHandler sync response is seen, replaced value continues', () {
      var handler = const Pipeline()
          .addMiddleware(createMiddleware(responseHandler: (response) {
        expect(response.headers['from'], 'handler');
        return _middlewareResponse;
      })).addHandler((request) {
        return syncHandler(request, headers: {'from': 'handler'});
      });

      return makeSimpleRequest(handler).then((response) {
        expect(response.headers['from'], 'middleware');
      });
    });

    test('innerHandler async response is seen, async value continues', () {
      var handler = const Pipeline()
          .addMiddleware(createMiddleware(responseHandler: (response) {
        expect(response.headers['from'], 'handler');
        return new Future.value(_middlewareResponse);
      })).addHandler((request) {
        return new Future(
            () => syncHandler(request, headers: {'from': 'handler'}));
      });

      return makeSimpleRequest(handler).then((response) {
        expect(response.headers['from'], 'middleware');
      });
    });
  });

  group('error handling', () {
    test('sync error thrown by requestHandler bubbles down', () {
      var handler = const Pipeline()
          .addMiddleware(createMiddleware(
              requestHandler: (request) => throw 'middleware error'))
          .addHandler(_failHandler);

      expect(makeSimpleRequest(handler), throwsA('middleware error'));
    });

    test('async error thrown by requestHandler bubbles down', () {
      var handler = const Pipeline()
          .addMiddleware(createMiddleware(
              requestHandler: (request) =>
                  new Future.error('middleware error')))
          .addHandler(_failHandler);

      expect(makeSimpleRequest(handler), throwsA('middleware error'));
    });

    test('throw from responseHandler does not hit error handler', () {
      var middleware = createMiddleware(
          responseHandler: (response) {
            throw 'middleware error';
          },
          errorHandler: (e, s) => fail('should never get here'));

      var handler =
          const Pipeline().addMiddleware(middleware).addHandler(syncHandler);

      expect(makeSimpleRequest(handler), throwsA('middleware error'));
    });

    test('requestHandler throw does not hit errorHandlers', () {
      var middleware = createMiddleware(
          requestHandler: (request) {
            throw 'middleware error';
          },
          errorHandler: (e, s) => fail('should never get here'));

      var handler =
          const Pipeline().addMiddleware(middleware).addHandler(syncHandler);

      expect(makeSimpleRequest(handler), throwsA('middleware error'));
    });

    test('inner handler throws, is caught by errorHandler with response', () {
      var middleware = createMiddleware(errorHandler: (error, stack) {
        expect(error, 'bad handler');
        return _middlewareResponse;
      });

      var handler =
          const Pipeline().addMiddleware(middleware).addHandler((request) {
        throw 'bad handler';
      });

      return makeSimpleRequest(handler).then((response) {
        expect(response.headers['from'], 'middleware');
      });
    });

    test('inner handler throws, is caught by errorHandler and rethrown', () {
      var middleware = createMiddleware(errorHandler: (error, stack) {
        expect(error, 'bad handler');
        throw error;
      });

      var handler =
          const Pipeline().addMiddleware(middleware).addHandler((request) {
        throw 'bad handler';
      });

      expect(makeSimpleRequest(handler), throwsA('bad handler'));
    });

    test(
        'error thrown by inner handler without a middleware errorHandler is '
        'rethrown', () {
      var middleware = createMiddleware();

      var handler =
          const Pipeline().addMiddleware(middleware).addHandler((request) {
        throw 'bad handler';
      });

      expect(makeSimpleRequest(handler), throwsA('bad handler'));
    });

    test("doesn't handle HijackException", () {
      var middleware = createMiddleware(errorHandler: (error, stack) {
        fail("error handler shouldn't be called");
      });

      var handler = const Pipeline()
          .addMiddleware(middleware)
          .addHandler((request) => throw const HijackException());

      expect(makeSimpleRequest(handler),
          throwsA(new isInstanceOf<HijackException>()));
    });
  });
}

Response _failHandler(Request request) {
  fail('should never get here');
  return null;
}

final Response _middlewareResponse =
    new Response.ok('middleware content', headers: {'from': 'middleware'});
