// 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:io';

import 'package:cocoon_service/src/request_handling/authentication.dart' show AuthenticatedContext;
import 'package:cocoon_service/src/request_handling/exceptions.dart';
import 'package:cocoon_service/src/request_handling/pubsub_authentication.dart';
import 'package:cocoon_service/src/service/config.dart';
import 'package:http/http.dart' as http;
import 'package:http/testing.dart';
import 'package:test/test.dart';

import '../src/datastore/fake_config.dart';
import '../src/request_handling/fake_authentication.dart';
import '../src/request_handling/fake_http.dart';

void main() {
  group('PubsubAuthenticationProvider', () {
    late FakeConfig config;
    late FakeClientContext clientContext;
    late FakeHttpRequest request;
    late PubsubAuthenticationProvider auth;
    late MockClient httpClient;

    setUp(() {
      config = FakeConfig();
      clientContext = FakeClientContext();
      request = FakeHttpRequest();
      auth = PubsubAuthenticationProvider(
        config: config,
        clientContextProvider: () => clientContext,
        httpClientProvider: () => httpClient,
      );
    });

    for (String allowedAccount in Config.allowedPubsubServiceAccounts) {
      test('auth succeeds for $allowedAccount', () async {
        httpClient = MockClient(
          (_) async => http.Response(
            _generateTokenResponse(allowedAccount),
            HttpStatus.ok,
            headers: <String, String>{
              HttpHeaders.contentTypeHeader: 'application/json',
            },
          ),
        );
        auth = PubsubAuthenticationProvider(
          config: config,
          clientContextProvider: () => clientContext,
          httpClientProvider: () => httpClient,
        );

        request.headers.add(HttpHeaders.authorizationHeader, 'Bearer token');

        final AuthenticatedContext result = await auth.authenticate(request);
        expect(result.clientContext, same(clientContext));
      });
    }

    test('auth fails with unauthorized service account', () async {
      httpClient = MockClient(
        (_) async => http.Response(
          _generateTokenResponse('unauthorized@gmail.com'),
          HttpStatus.ok,
          headers: <String, String>{
            HttpHeaders.contentTypeHeader: 'application/json',
          },
        ),
      );
      auth = PubsubAuthenticationProvider(
        config: config,
        clientContextProvider: () => clientContext,
        httpClientProvider: () => httpClient,
      );

      request.headers.add(HttpHeaders.authorizationHeader, 'Bearer token');

      expect(auth.authenticate(request), throwsA(isA<Unauthenticated>()));
    });

    test('auth fails with invalid token', () async {
      httpClient = MockClient(
        (_) async => http.Response(
          'Invalid token',
          HttpStatus.unauthorized,
          headers: <String, String>{
            HttpHeaders.contentTypeHeader: 'application/json',
          },
        ),
      );
      auth = PubsubAuthenticationProvider(
        config: config,
        clientContextProvider: () => clientContext,
        httpClientProvider: () => httpClient,
      );

      request.headers.add(HttpHeaders.authorizationHeader, 'Bearer token');

      expect(auth.authenticate(request), throwsA(isA<FormatException>()));
    });

    test('auth fails with expired token', () async {
      httpClient = MockClient(
        (_) async => http.Response(
          _generateTokenResponse(
            Config.allowedPubsubServiceAccounts.first,
            expiresIn: -1,
          ),
          HttpStatus.ok,
          headers: <String, String>{
            HttpHeaders.contentTypeHeader: 'application/json',
          },
        ),
      );
      auth = PubsubAuthenticationProvider(
        config: config,
        clientContextProvider: () => clientContext,
        httpClientProvider: () => httpClient,
      );

      request.headers.add(HttpHeaders.authorizationHeader, 'Bearer token');

      expect(auth.authenticate(request), throwsA(isA<Unauthenticated>()));
    });
  });
}

/// Return Google's OAuth response.
String _generateTokenResponse(
  String email, {
  int expiresIn = 123,
}) {
  return '''{
            "issued_to": "456",
            "audience": "https://flutter-dashboard.appspot.com/api/luci-status-handler",
            "user_id": "789",
            "expires_in": $expiresIn,
            "email": "$email",
            "verified_email": true,
            "issuer": "https://accounts.google.com",
            "issued_at": 412321
          }''';
}
