// Copyright (c) 2019, 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:convert';
import 'dart:js_util';

import 'package:firebase_admin_interop/firebase_admin_interop.dart';
import 'package:js/js.dart';
import 'package:node_http/node_http.dart' as http_client;
import 'package:node_interop/http.dart' show http, HttpServer;
import 'package:node_interop/node_interop.dart';
import 'package:node_interop/util.dart' show dartify, jsify;
import 'package:node_io/node_io.dart' hide HttpServer;
import 'package:symbolizer/model.dart';
import 'package:test/test.dart';

import 'package:github_label_notifier/github_utils.dart';

// Note: must match project-id used in test.sh
final String projectId = 'github-label-notifier';

void main() async {
  if (!Platform.environment.containsKey('FIRESTORE_EMULATOR_HOST')) {
    throw 'This test must run in an emulated environment via test.sh script';
  }

  // Mock SendGrid server which simply records all requests it recieves.
  HttpServer sendgridMockServer;
  final sendgridRequests = <SendgridRequest>[];

  HttpServer symbolizerServer;
  final symbolizerCommands = <String>[];

  setUpAll(() async {
    // Populate firestore with mock data.
    final firestore = FirebaseAdmin.instance
        .initializeApp(AppOptions(projectId: projectId))
        .firestore();
    final subscriptions = firestore.collection('github-label-subscriptions');

    for (var doc in (await subscriptions.get()).documents) {
      await doc.reference.delete();
    }

    await subscriptions.add(DocumentData.fromMap({
      'email': 'first@example.com',
      'subscriptions': [
        'dart-lang/webhook-test:some-label',
        'dart-lang/webhook-test:feature',
      ],
    }));
    await subscriptions.add(DocumentData.fromMap({
      'email': 'second@example.com',
      'subscriptions': [
        'dart-lang/webhook-test:bug',
        'dart-lang/webhook-test:feature',
        'dart-lang/webhook-test:special-label',
      ],
    }));

    await firestore
        .document('github-keyword-subscriptions/dart-lang\$webhook-test')
        .setData(DocumentData.fromMap({
          'keywords': [
            'jit',
            'aot',
            'third_party/dart',
            'crash',
          ],
          'label': 'special-label',
        }));

    {
      // Start mock SendGrid server at the address/port specified in
      // SENDGRID_MOCK_SERVER environment variable.
      // This server will simply record headers and bodies of all requests
      // it receives in the [sendgridRequests] variable.
      sendgridMockServer = http.createServer(allowInterop((rq, rs) {
        final body = [];
        rq.on('data', allowInterop((chunk) {
          body.add(chunk);
        }));
        rq.on('end', allowInterop(() {
          sendgridRequests.add(SendgridRequest(
              headers: dartify(rq.headers),
              body: jsonDecode(_bufferToString(Buffer.concat(body)))));

          // Reply with 200 OK.
          rs.writeHead(200, 'OK', jsify({'Content-Type': 'text/plain'}));
          rs.write('OK');
          rs.end();
        }));
      }));

      final serverAddress = Platform.environment['SENDGRID_MOCK_SERVER'];
      if (serverAddress == null) {
        throw 'SENDGRID_MOCK_SERVER environment variable is not set';
      }
      final serverUri = Uri.parse('http://$serverAddress');
      sendgridMockServer.listen(serverUri.port, serverUri.host);
    }

    {
      // Start mock Symbolizer server at the address/port specified in
      // SYMBOLIZER_SERVER environment variable.
      symbolizerServer = http.createServer(allowInterop((rq, rs) {
        final body = [];
        rq.on('data', allowInterop((chunk) {
          body.add(chunk);
        }));
        rq.on('end', allowInterop(() {
          switch (Uri.parse(rq.url).path) {
            case '/symbolize':
              // Reply with symbolized crash.
              rs.writeHead(
                  200, 'OK', jsify({'Content-Type': 'application/json'}));
              rs.write(jsonEncode([
                SymbolizationResult(
                    crash: Crash(
                        engineVariant: EngineVariant(
                            arch: 'arm', os: 'ios', mode: 'debug'),
                        format: 'native',
                        frames: [
                          CrashFrame.ios(
                            no: '00',
                            binary: 'BINARY',
                            pc: 0x10042,
                            symbol: '0x',
                            offset: 42,
                            location: '',
                          )
                        ]),
                    engineBuild: EngineBuild(
                      engineHash: 'aaabbb',
                      variant:
                          EngineVariant(arch: 'arm', os: 'ios', mode: 'debug'),
                    ),
                    symbolized: 'SYMBOLIZED_STACK_HERE')
              ]));
              rs.end();
              break;
            case '/command':
              symbolizerCommands.add(
                  jsonDecode(_bufferToString(Buffer.concat(body)))['comment']
                      ['body']);

              // Reply with 200 OK.
              rs.writeHead(200, 'OK', jsify({'Content-Type': 'text/plain'}));
              rs.write('OK');
              rs.end();
              break;
            default:
              // Reply with 404.
              rs.writeHead(
                  404, 'Not Found', jsify({'Content-Type': 'text/plain'}));
              rs.write('Not Found');
              rs.end();
              break;
          }
        }));
      }));

      final serverAddress = Platform.environment['SYMBOLIZER_SERVER'];
      if (serverAddress == null) {
        throw 'SENDGRID_MOCK_SERVER environment variable is not set';
      }
      final serverUri = Uri.parse('http://$serverAddress');
      symbolizerServer.listen(serverUri.port, serverUri.host);
    }
  });

  setUp(() {
    sendgridRequests.clear();
    symbolizerCommands.clear();
  });

  tearDownAll(() async {
    // Shutdown the mock SendGrid server.
    await sendgridMockServer.close();

    // Shutdown the mock symbolizer.
    await symbolizerServer.close();
  });

  // Helper to send a mock GitHub event to the locally running instance of the
  // webhook.
  Future<http_client.Response> sendEvent({
    String delivery = '7e754400-fa9b-11e9-9421-bb996f50ac6b',
    String event = 'issues',
    String signature,
    Map<String, dynamic> body,
  }) async {
    final headers = {
      'content-type': 'application/json',
    };

    if (delivery != null) {
      headers['X-GitHub-Delivery'] = delivery;
    }

    if (event != null) {
      headers['X-GitHub-Event'] = event;
    }

    final encodedBody = jsonEncode(body);
    if (signature != '') {
      headers['X-Hub-Signature'] = signature ?? signEvent(encodedBody);
    }

    // Note: there does not seem to be a good way to get a trigger uri for
    // a function when running the test suite.
    return await http_client.post(
        'http://localhost:5001/$projectId/us-central1/githubWebhook',
        headers: headers,
        body: encodedBody);
  }

  // Create mock event body.
  Map<String, dynamic> makeLabeledEvent(
          {String labelName = 'bug', int number = 1}) =>
      {
        'action': 'labeled',
        'issue': {
          'html_url':
              'https://github.com/dart-lang/webhook-test/issues/${number}',
          'number': number,
          'title': 'TEST ISSUE TITLE',
          'user': {
            'login': 'hest',
            'html_url': 'https://github.com/hest',
          },
        },
        'label': {
          'name': labelName,
        },
        'repository': {
          'full_name': 'dart-lang/webhook-test',
        },
        'sender': {
          'login': 'fisk',
          'html_url': 'https://github.com/fisk',
        }
      };

  Map<String, dynamic> makeIssueOpenedEvent(
          {int number = 1,
          String repositoryName = 'dart-lang/webhook-test',
          String body =
              'This is an amazing ../third_party/dart/runtime/vm solution'}) =>
      {
        'action': 'opened',
        'issue': {
          'html_url':
              'https://github.com/dart-lang/webhook-test/issues/${number}',
          'number': number,
          'title': 'TEST ISSUE TITLE',
          'body': body,
          'user': {
            'login': 'hest',
            'html_url': 'https://github.com/hest',
          },
        },
        'repository': {
          'full_name': 'dart-lang/webhook-test',
        },
      };

  Map<String, dynamic> makeIssueCommentEvent(
          {int number = 1,
          String repositoryName = 'dart-lang/webhook-test',
          String issueBody =
              'This is an amazing ../third_party/dart/runtime/vm solution',
          String commentBody = 'comment body goes here',
          String authorAssociation = 'NONE'}) =>
      {
        'action': 'created',
        'issue': {
          'html_url':
              'https://github.com/dart-lang/webhook-test/issues/${number}',
          'number': number,
          'title': 'TEST ISSUE TITLE',
          'body': issueBody,
          'user': {
            'login': 'hest',
            'html_url': 'https://github.com/hest',
          },
        },
        'comment': {
          'body': commentBody,
          'author_association': authorAssociation,
        },
        'repository': {
          'full_name': 'dart-lang/webhook-test',
        },
      };

  test('signing', () {
    expect(signEvent(jsonEncode(makeLabeledEvent(labelName: 'bug'))),
        equals('sha1=76af51cdb9c7a43b146d4df721ac8f83e53182e5'));
  });

  test('reject malformed request - no delivery', () async {
    final rs = await sendEvent(body: {}, delivery: null);
    expect(rs.statusCode, equals(HttpStatus.badRequest));
    expect(sendgridRequests, isEmpty);
  });

  test('reject malformed request - no event', () async {
    final rs = await sendEvent(body: {}, event: null);
    expect(rs.statusCode, equals(HttpStatus.badRequest));
    expect(sendgridRequests, isEmpty);
  });

  test('reject malformed request - no signature', () async {
    final rs = await sendEvent(
        body: makeLabeledEvent(labelName: 'bug'), signature: '');
    expect(rs.statusCode, equals(HttpStatus.badRequest));
    expect(sendgridRequests, isEmpty);
  });

  test('reject incorrectly signed request', () async {
    final rs = await sendEvent(
        body: makeLabeledEvent(labelName: 'bug'),
        signature: 'sha1=76af51cdb9c7a43b246d4df721ac8f83e53182e5');
    expect(rs.statusCode, equals(HttpStatus.unauthorized));
    expect(sendgridRequests, isEmpty);
  });

  test('ok - ignore wrong event', () async {
    final rs = await sendEvent(
        body: makeLabeledEvent(labelName: 'bug'), event: 'wrong-type');
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(sendgridRequests, isEmpty);
  });

  test('ok - ignore wrong action', () async {
    final rs = await sendEvent(body: {'action': 'deleted'});
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(sendgridRequests, isEmpty);
  });

  test('ok - no subscribers', () async {
    final rs =
        await sendEvent(body: makeLabeledEvent(labelName: 'performance'));
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(sendgridRequests, isEmpty);
  });

  test('ok - single subscriber', () async {
    final rs = await sendEvent(body: makeLabeledEvent(labelName: 'bug'));
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(sendgridRequests.length, equals(1));

    final rq = sendgridRequests.first;
    expect(rq.headers['authorization'],
        equals('Bearer ' + Platform.environment['SENDGRID_SECRET']));
    expect(rq.body['subject'], contains('bug'));
    expect(rq.body['subject'], contains('#1'));
    expect(rq.body['subject'], contains('TEST ISSUE TITLE'));
    expect(
        rq.body['personalizations'],
        unorderedEquals([
          {
            'to': [
              {'email': 'second@example.com'}
            ]
          }
        ]));
  });

  test('ok - multiple subscribers', () async {
    final rs = await sendEvent(
        body: makeLabeledEvent(labelName: 'feature', number: 2));
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(sendgridRequests.length, equals(1));

    final rq = sendgridRequests.first;
    expect(rq.headers['authorization'],
        equals('Bearer ' + Platform.environment['SENDGRID_SECRET']));
    expect(rq.body['subject'], contains('feature'));
    expect(rq.body['subject'], contains('#2'));
    expect(rq.body['subject'], contains('TEST ISSUE TITLE'));
    expect(
        rq.body['personalizations'],
        unorderedEquals([
          {
            'to': [
              {'email': 'second@example.com'}
            ]
          },
          {
            'to': [
              {'email': 'first@example.com'}
            ]
          }
        ]));
  });

  test('ok - issue opened', () async {
    final rs = await sendEvent(body: makeIssueOpenedEvent());
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(sendgridRequests.length, equals(1));

    final rq = sendgridRequests.first;
    expect(rq.headers['authorization'],
        equals('Bearer ' + Platform.environment['SENDGRID_SECRET']));
    expect(rq.body['subject'], contains('#1'));
    expect(rq.body['subject'], contains('TEST ISSUE TITLE'));
    expect(
        rq.body['personalizations'],
        unorderedEquals([
          {
            'to': [
              {'email': 'second@example.com'}
            ]
          }
        ]));
    expect(
        rq.body['content']
            .firstWhere((c) => c['type'] == 'text/plain')['value'],
        contains('Matches keyword: third_party/dart'));
  });

  test('ok - issue opened - test underscore as word boundary', () async {
    final rs = await sendEvent(
        body: makeIssueOpenedEvent(
            body: 'xyz, something_jit_something_else, foobar'));
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(sendgridRequests.length, equals(1));

    final rq = sendgridRequests.first;
    expect(rq.headers['authorization'],
        equals('Bearer ' + Platform.environment['SENDGRID_SECRET']));
    expect(rq.body['subject'], contains('#1'));
    expect(rq.body['subject'], contains('TEST ISSUE TITLE'));
    expect(
        rq.body['personalizations'],
        unorderedEquals([
          {
            'to': [
              {'email': 'second@example.com'}
            ]
          }
        ]));
    expect(
        rq.body['content']
            .firstWhere((c) => c['type'] == 'text/plain')['value'],
        contains('Matches keyword: jit'));
  });

  test('ok - issue opened - no matching keyword', () async {
    final rs = await sendEvent(
        body: makeIssueOpenedEvent(
            body: 'xyz, somethingjitsomething_else, foobar'));
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(sendgridRequests.length, equals(0));
  });

  test('ok - issue opened - crash', () async {
    final rs = await sendEvent(body: makeIssueOpenedEvent(body: '''
I had Flutter engine c_r_a_s_h on me with the following message

*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***
Such c_r_a_s_h
Much information
'''));
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(sendgridRequests.length, equals(1));
    final rq = sendgridRequests.first;
    final plainTextBody = rq.body['content']
        .firstWhere((c) => c['type'] == 'text/plain')['value'];
    expect(plainTextBody, contains('engine aaabbb ios-arm-debug crash'));
    expect(plainTextBody, contains('SYMBOLIZED_STACK_HERE'));
  });

  test('ok - issue comment - forward bot command', () async {
    final command = '''@flutter-symbolizer-bot aaa bbb''';
    final rs = await sendEvent(
        event: 'issue_comment',
        body: makeIssueCommentEvent(
          commentBody: command,
          authorAssociation: 'MEMBER',
        ));
    expect(rs.statusCode, equals(HttpStatus.ok));
    expect(symbolizerCommands, equals([command]));
  });
}

/// Helper method to convert a [Buffer] to a [String].
///
/// Just calling [Buffer.toString] invokes the wrong method
/// (see https://dartbug.com/30096).
String _bufferToString(Buffer buf) {
  return callMethod(buf, 'toString', []);
}

/// Request that arrived to the mock SendGrid server.
class SendgridRequest {
  final Map<String, dynamic> headers;
  final Map<String, dynamic> body;

  SendgridRequest({this.headers, this.body});

  Map<String, dynamic> toJson() => {'headers': headers, 'body': body};
}
