// Copyright 2019 The Flutter Authors. 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:convert';
import 'dart:io';

import 'package:cocoon_service/src/request_handling/body.dart';
import 'package:cocoon_service/src/request_handling/exceptions.dart';
import 'package:cocoon_service/src/request_handling/request_handler.dart';
import 'package:cocoon_service/src/service/logging.dart';
import 'package:gcloud/service_scope.dart' as ss;
import 'package:logging/logging.dart';
import 'package:test/test.dart';

import '../src/datastore/fake_config.dart';

void main() {
  group('RequestHandler', () {
    late HttpServer server;
    late RequestHandler<dynamic> handler;

    final List<LogRecord> records = <LogRecord>[];

    setUpAll(() async {
      server = await HttpServer.bind(InternetAddress.loopbackIPv4, 0);
      server.listen((HttpRequest request) {
        runZoned<dynamic>(() {
          return ss.fork(() {
            return handler.service(request);
          });
        });
      });
    });

    tearDownAll(() async {
      await server.close();
    });

    setUp(() {
      records.clear();
      log.onRecord.listen((LogRecord record) => records.add(record));
    });

    Future<HttpClientResponse> issueRequest(String method) async {
      final HttpClient client = HttpClient();
      final Uri url = Uri(scheme: 'http', host: 'localhost', port: server.port, path: '/path');
      final HttpClientRequest request = await client.openUrl(method, url);
      return await request.close();
    }

    Future<HttpClientResponse> issueGet() => issueRequest('get');

    Future<HttpClientResponse> issuePost() => issueRequest('post');

    test('Unimplemented methods yield HTTP method not allowed', () async {
      handler = MethodNotAllowed();
      HttpClientResponse response = await issueGet();
      expect(response.statusCode, HttpStatus.methodNotAllowed);
      response = await issuePost();
      expect(response.statusCode, HttpStatus.methodNotAllowed);
      expect(records, isEmpty);
    });

    test('empty body yields empty HTTP response body', () async {
      handler = EmptyBodyHandler();
      final HttpClientResponse response = await issueGet();
      expect(response.statusCode, HttpStatus.ok);
      expect(await response.toList(), isEmpty);
      expect(records, isEmpty);
    });

    test('string body yields string HTTP response body', () async {
      handler = StringBodyHandler();
      final HttpClientResponse response = await issueGet();
      expect(response.statusCode, HttpStatus.ok);
      expect(await utf8.decoder.bind(response).join(), 'Hello world');
      expect(records, isEmpty);
    });

    test('JsonBody yields JSON HTTP response body', () async {
      handler = JsonBodyHandler();
      final HttpClientResponse response = await issueGet();
      expect(response.statusCode, HttpStatus.ok);
      expect(await utf8.decoder.bind(response).join(), '{"key":"value"}');
      expect(records, isEmpty);
    });

    test('throwing HttpException yields corresponding HTTP status', () async {
      handler = ThrowsHttpException();
      final HttpClientResponse response = await issueGet();
      expect(response.statusCode, HttpStatus.badRequest);
      expect(await utf8.decoder.bind(response).join(), 'Bad request');
      expect(records, isEmpty);
    });

    test('throwing general exception yields HTTP 500 and logs to server logs', () async {
      handler = ThrowsStateError();
      final HttpClientResponse response = await issueGet();
      expect(response.statusCode, HttpStatus.internalServerError);
      expect(await utf8.decoder.bind(response).join(), contains('error message'));
      expect(records.first.message, contains('error message'));
    });

    test('may access the request and response directly', () async {
      handler = AccessesRequestAndResponseDirectly();
      final HttpClientResponse response = await issueGet();
      expect(response.headers.value('X-Test-Path'), '/path');
      expect(records, isEmpty);
    });

    test('may implement both GET and POST', () async {
      handler = ImplementsBothGetAndPost();
      HttpClientResponse response = await issueGet();
      expect(response.headers.value('X-Test-Get'), 'true');
      expect(response.headers.value('X-Test-Post'), isNull);
      response = await issuePost();
      expect(response.headers.value('X-Test-Get'), isNull);
      expect(response.headers.value('X-Test-Post'), 'true');
      expect(records, isEmpty);
    });

    test('may implement only POST', () async {
      handler = ImplementsOnlyPost();
      HttpClientResponse response = await issueGet();
      expect(response.statusCode, HttpStatus.methodNotAllowed);
      response = await issuePost();
      expect(response.statusCode, HttpStatus.ok);
      expect(records, isEmpty);
    });
  });
}

class TestBody extends JsonBody {
  const TestBody();

  @override
  Map<String, dynamic> toJson() => const <String, dynamic>{'key': 'value'};
}

class MethodNotAllowed extends RequestHandler<Body> {
  MethodNotAllowed() : super(config: FakeConfig());
}

class EmptyBodyHandler extends RequestHandler<Body> {
  EmptyBodyHandler() : super(config: FakeConfig());

  @override
  Future<Body> get() async => Body.empty;
}

class StringBodyHandler extends RequestHandler<Body> {
  StringBodyHandler() : super(config: FakeConfig());

  @override
  Future<Body> get() async => Body.forString('Hello world');
}

class JsonBodyHandler extends RequestHandler<TestBody> {
  JsonBodyHandler() : super(config: FakeConfig());

  @override
  Future<TestBody> get() async => const TestBody();
}

class ThrowsHttpException extends RequestHandler<Body> {
  ThrowsHttpException() : super(config: FakeConfig());

  @override
  Future<Body> get() async => throw const BadRequestException();
}

class ThrowsStateError extends RequestHandler<Body> {
  ThrowsStateError() : super(config: FakeConfig());

  @override
  Future<Body> get() async => throw StateError('error message');
}

class AccessesRequestAndResponseDirectly extends RequestHandler<Body> {
  AccessesRequestAndResponseDirectly() : super(config: FakeConfig());

  @override
  Future<Body> get() async {
    response!.headers.add('X-Test-Path', request!.uri.path);
    return Body.empty;
  }
}

class ImplementsBothGetAndPost extends RequestHandler<Body> {
  ImplementsBothGetAndPost() : super(config: FakeConfig());

  @override
  Future<Body> get() async {
    response!.headers.add('X-Test-Get', 'true');
    return Body.empty;
  }

  @override
  Future<Body> post() async {
    response!.headers.add('X-Test-Post', 'true');
    return Body.empty;
  }
}

class ImplementsOnlyPost extends RequestHandler<Body> {
  ImplementsOnlyPost() : super(config: FakeConfig());

  @override
  Future<Body> post() async => Body.empty;
}
