// Copyright (c) 2022, 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.

@JS()
library;

import 'dart:async';
import 'dart:convert';
// TODO: https://github.com/dart-lang/webdev/issues/2508
// ignore: deprecated_member_use
import 'dart:js_util';

// TODO: https://github.com/dart-lang/webdev/issues/2508
// ignore: deprecated_member_use
import 'package:js/js.dart';

import 'chrome_api.dart';
import 'data_serializers.dart';
import 'logger.dart';
import 'utils.dart';

// A default response for the sendResponse callback.
//
// Prevents the message port from closing. See:
// https://developer.chrome.com/docs/extensions/mv3/messaging/#simple
final defaultResponse = jsify({'response': 'received'});

enum Script {
  background,
  copier,
  debuggerPanel,
  detector,
  popup;

  factory Script.fromString(String value) {
    return Script.values.byName(value);
  }
}

enum MessageType {
  isAuthenticated,
  connectFailure,
  appId,
  debugInfo,
  debugStateChange,
  devToolsUrl,
  multipleAppsDetected;

  factory MessageType.fromString(String value) {
    return MessageType.values.byName(value);
  }
}

class Message {
  final Script to;
  final Script from;
  final MessageType type;
  final String body;
  final String? error;

  Message({
    required this.to,
    required this.from,
    required this.type,
    required this.body,
    this.error,
  });

  factory Message.fromJSON(String json) {
    final decoded = jsonDecode(json) as Map<String, dynamic>;

    return Message(
      to: Script.fromString(decoded['to'] as String),
      from: Script.fromString(decoded['from'] as String),
      type: MessageType.fromString(decoded['type'] as String),
      body: decoded['body'] as String,
      error: decoded['error'] as String?,
    );
  }

  String toJSON() {
    return jsonEncode({
      'to': to.name,
      'from': from.name,
      'type': type.name,
      'body': body,
      if (error != null) 'error': error,
    });
  }
}

void interceptMessage<T>({
  required String? message,
  required MessageType expectedType,
  required Script expectedSender,
  required Script expectedRecipient,
  required MessageSender sender,
  required void Function(T message) messageHandler,
}) {
  if (message == null) return;
  if (!_isLegitimateSender(sender)) return;

  try {
    final decodedMessage = Message.fromJSON(message);
    if (decodedMessage.type != expectedType ||
        decodedMessage.to != expectedRecipient ||
        decodedMessage.from != expectedSender) {
      return;
    }
    if (T == String) {
      messageHandler(decodedMessage.body as T);
    } else {
      messageHandler(
        serializers.deserialize(jsonDecode(decodedMessage.body)) as T,
      );
    }
  } catch (error) {
    debugError(
      'Error intercepting $expectedType from '
      '$expectedSender to $expectedRecipient: $error',
    );
  }
}

/// Send a message using the chrome.runtime.sendMessage API.
Future<bool> sendRuntimeMessage({
  required MessageType type,
  required String body,
  required Script sender,
  required Script recipient,
}) =>
    _sendMessage(type: type, body: body, sender: sender, recipient: recipient);

/// Send a message using the chrome.tabs.sendMessage API.
Future<bool> sendTabsMessage({
  required int tabId,
  required MessageType type,
  required String body,
  required Script sender,
  required Script recipient,
}) => _sendMessage(
  tabId: tabId,
  type: type,
  body: body,
  sender: sender,
  recipient: recipient,
);

Future<bool> _sendMessage({
  required MessageType type,
  required String body,
  required Script sender,
  required Script recipient,
  int? tabId,
}) {
  final message =
      Message(to: recipient, from: sender, type: type, body: body).toJSON();
  final completer = Completer<bool>();
  void responseHandler([dynamic _]) {
    final error = chrome.runtime.lastError;
    if (error != null) {
      debugError(
        'Error sending $type to $recipient from $sender: ${error.message}',
      );
    }
    completer.complete(error != null);
  }

  if (tabId != null) {
    chrome.tabs.sendMessage(
      tabId,
      message,
      // options
      null,
      allowInterop(responseHandler),
    );
  } else {
    chrome.runtime.sendMessage(
      // id
      null,
      message,
      // options
      null,
      allowInterop(responseHandler),
    );
  }
  return completer.future;
}

// Verify the message sender is our extension.
bool _isLegitimateSender(MessageSender sender) {
  // Check that the sender ID matches our extension ID:
  if (sender.id != chrome.runtime.id) return false;

  final senderUri = Uri.parse(sender.origin ?? '');
  final senderHost = senderUri.host;
  final isDartAppHost =
      senderHost == 'localhost' ||
      senderHost == '127.0.0.1' ||
      _isGoogleHost(senderHost);
  final isExtensionOrigin =
      senderHost == chrome.runtime.id && senderUri.scheme == 'chrome-extension';

  if (isDartAppHost || isExtensionOrigin) return true;

  // If the sender's host is unexpected, display an error.
  displayNotification(
    'Unexpected sender ${sender.origin}. Please file a bug at go/dde-bug or https://github.com/dart-lang/webdev',
    isError: true,
  );
  return false;
}

bool _isGoogleHost(String host) {
  const googleSuffices = ['.googlers.com', '.google.com', '.googleprod.com'];
  return googleSuffices.any((suffix) => host.endsWith(suffix));
}
