// 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:convert';
// TODO: https://github.com/dart-lang/webdev/issues/2508
// ignore: deprecated_member_use
import 'dart:html';
// TODO: https://github.com/dart-lang/webdev/issues/2508
// ignore: deprecated_member_use
import 'dart:js_util';

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

import 'chrome_api.dart';
import 'logger.dart';
import 'messaging.dart';

const _multipleAppsAttribute = 'data-multiple-dart-apps';

void main() {
  _registerListeners();
}

void _registerListeners() {
  document.addEventListener('dart-app-ready', _onDartAppReadyEvent);
  document.addEventListener('dart-auth-response', _onDartAuthEvent);
}

Future<void> _onDartAppReadyEvent(Event event) async {
  final debugInfo = getProperty(event, 'detail') as String?;
  if (debugInfo == null) {
    debugWarn(
      'No debug info sent with ready event, instead reading from Window.',
    );
    _injectDebugInfoScript();
  } else {
    await _sendMessageToBackgroundScript(
      type: MessageType.debugInfo,
      body: debugInfo,
    );
    _sendAuthRequest(debugInfo);
    _detectMultipleDartApps();
  }
}

Future<void> _onDartAuthEvent(Event event) async {
  final isAuthenticated = getProperty(event, 'detail') as String?;
  if (isAuthenticated == null) return;
  await _sendMessageToBackgroundScript(
    type: MessageType.isAuthenticated,
    body: isAuthenticated,
  );
}

void _detectMultipleDartApps() {
  final documentElement = document.documentElement;
  if (documentElement == null) return;

  if (documentElement.hasAttribute(_multipleAppsAttribute)) {
    _sendMessageToBackgroundScript(
      type: MessageType.multipleAppsDetected,
      body: 'true',
    );
    return;
  }

  final multipleAppsObserver = MutationObserver(
    _detectMultipleDartAppsCallback,
  );
  multipleAppsObserver.observe(
    documentElement,
    attributeFilter: [_multipleAppsAttribute],
  );
}

void _detectMultipleDartAppsCallback(
  List<dynamic> mutations,
  MutationObserver observer,
) {
  for (final mutation in mutations) {
    if (_isMultipleAppsMutation(mutation)) {
      _sendMessageToBackgroundScript(
        type: MessageType.multipleAppsDetected,
        body: 'true',
      );
      observer.disconnect();
    }
  }
}

bool _isMultipleAppsMutation(dynamic mutation) {
  final isAttributeMutation =
      hasProperty(mutation, 'type') &&
      getProperty(mutation, 'type') == 'attributes';
  if (isAttributeMutation) {
    return hasProperty(mutation, 'attributeName') &&
        getProperty(mutation, 'attributeName') == _multipleAppsAttribute;
  }
  return false;
}

// TODO(elliette): Remove once DWDS 17.0.0 is in Flutter stable. If we are on an
// older version of DWDS, then the debug info is not sent along with the ready
// event. Therefore we must read it from the Window object, which is slower.
void _injectDebugInfoScript() {
  final script = document.createElement('script');
  final scriptSrc = chrome.runtime.getURL('debug_info.dart.js');
  script.setAttribute('src', scriptSrc);
  script.setAttribute('defer', true);
  document.head?.append(script);
}

Future<void> _sendMessageToBackgroundScript({
  required MessageType type,
  required String body,
}) async {
  await sendRuntimeMessage(
    type: type,
    body: body,
    sender: Script.detector,
    recipient: Script.background,
  );
}

void _sendAuthRequest(String debugInfoJson) {
  final debugInfo = DebugInfo.fromJson(
    jsonDecode(debugInfoJson) as List<dynamic>,
  );
  final appOrigin = debugInfo.appOrigin;
  if (appOrigin != null) {
    window.postMessage('dart-auth-request', appOrigin);
  }
}
