// Copyright 2022 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 'package:cocoon_server/logging.dart';
import 'package:crypto/crypto.dart';
import 'package:github/github.dart';
import 'package:shelf/shelf.dart';

import '../request_handling/pubsub.dart';
import '../requests/exceptions.dart';
import '../server/request_handler.dart';
import '../service/config.dart';

/// Handler for processing GitHub webhooks.
///
/// On events where an 'autosubmit' label was added to a pull request,
/// check if the pull request is mergable and publish to pubsub.
class GithubWebhook extends RequestHandler {
  const GithubWebhook({required super.config, this.pubsub = const PubSub()});

  final PubSub pubsub;

  static const String pullRequest = 'pull_request';
  static const String labels = 'labels';
  static const String action = 'action';
  static const String sender = 'sender';

  static const String eventTypeHeader = 'X-GitHub-Event';
  static const String signatureHeader = 'X-Hub-Signature';

  @override
  Future<Response> post(Request request) async {
    final reqHeader = request.headers;
    log.info('Header: $reqHeader');

    final gitHubEvent = request.headers[GithubWebhook.eventTypeHeader];

    if (gitHubEvent == null ||
        request.headers[GithubWebhook.signatureHeader] == null) {
      throw const BadRequestException('Missing required headers.');
    }
    final requestBytes = await request
        .read()
        .expand((bodyBytes) => bodyBytes)
        .toList();
    final hmacSignature = request.headers[GithubWebhook.signatureHeader];
    if (!await _validateRequest(hmacSignature, requestBytes)) {
      log.info('User is forbidden');
      throw const Forbidden();
    }

    var hasAutosubmit = false;
    final rawBody = utf8.decode(requestBytes);
    final body = json.decode(rawBody) as Map<String, dynamic>;

    if (!body.containsKey(GithubWebhook.pullRequest) ||
        !(body[GithubWebhook.pullRequest] as Map<String, dynamic>).containsKey(
          GithubWebhook.labels,
        )) {
      return Response.ok(jsonEncode(<String, String>{}));
    }

    final pullRequest = PullRequest.fromJson(
      body[GithubWebhook.pullRequest] as Map<String, dynamic>,
    );

    hasAutosubmit = pullRequest.labels!.any(
      (label) => label.name == Config.kAutosubmitLabel,
    );

    if (hasAutosubmit) {
      log.info('Found pull request with autosubmit label.');
      await pubsub.publish(config.pubsubPullRequestTopic, pullRequest);
    }

    return Response.ok(rawBody);
  }

  Future<bool> _validateRequest(
    String? signature,
    List<int> requestBody,
  ) async {
    final rawKey = await config.getWebhookKey();
    final List<int> key = utf8.encode(rawKey);
    final hmac = Hmac(sha1, key);
    final digest = hmac.convert(requestBody);
    final bodySignature = 'sha1=$digest';
    return bodySignature == signature;
  }
}
