// Copyright 2013 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:html' as html;
import 'dart:typed_data';

import 'package:test/test.dart';
import 'package:ui/src/engine.dart' show flutterViewEmbedder, toMatrix32;
import 'package:ui/src/engine/browser_detection.dart';
import 'package:ui/src/engine/host_node.dart';
import 'package:ui/src/engine/semantics.dart';
import 'package:ui/src/engine/util.dart';
import 'package:ui/src/engine/vector_math.dart';
import 'package:ui/ui.dart' as ui;

import '../../matchers.dart';

/// Gets the DOM host where the Flutter app is being rendered.
///
/// This function returns the correct host for the flutter app under testing,
/// so we don't have to hardcode html.document across the test. (The host of a
/// normal flutter app used to be html.document, but now that the app is wrapped
/// in a Shadow DOM, that's not the case anymore.)
HostNode get appHostNode => flutterViewEmbedder.glassPaneShadow!;

/// CSS style applied to the root of the semantics tree.
// TODO(yjbanov): this should be handled internally by [expectSemanticsTree].
//                No need for every test to inject it.
final String rootSemanticStyle = browserEngine != BrowserEngine.edge
  ? 'filter: opacity(0%); color: rgba(0, 0, 0, 0)'
  : 'color: rgba(0, 0, 0, 0); filter: opacity(0%)';

/// A convenience wrapper of the semantics API for building and inspecting the
/// semantics tree in unit tests.
class SemanticsTester {
  SemanticsTester(this.owner);

  final EngineSemanticsOwner owner;
  final List<SemanticsNodeUpdate> _nodeUpdates = <SemanticsNodeUpdate>[];

  /// Updates one semantics node.
  ///
  /// Provides reasonable defaults for the missing attributes, and conveniences
  /// for specifying flags, such as [isTextField].
  SemanticsNodeUpdate updateNode({
    required int id,

    // Flags
    int flags = 0,
    bool? hasCheckedState,
    bool? isChecked,
    bool? isSelected,
    bool? isButton,
    bool? isLink,
    bool? isTextField,
    bool? isReadOnly,
    bool? isFocusable,
    bool? isFocused,
    bool? hasEnabledState,
    bool? isEnabled,
    bool? isInMutuallyExclusiveGroup,
    bool? isHeader,
    bool? isObscured,
    bool? scopesRoute,
    bool? namesRoute,
    bool? isHidden,
    bool? isImage,
    bool? isLiveRegion,
    bool? hasToggledState,
    bool? isToggled,
    bool? hasImplicitScrolling,
    bool? isMultiline,
    bool? isSlider,
    bool? isKeyboardKey,

    // Actions
    int actions = 0,
    bool? hasTap,
    bool? hasLongPress,
    bool? hasScrollLeft,
    bool? hasScrollRight,
    bool? hasScrollUp,
    bool? hasScrollDown,
    bool? hasIncrease,
    bool? hasDecrease,
    bool? hasShowOnScreen,
    bool? hasMoveCursorForwardByCharacter,
    bool? hasMoveCursorBackwardByCharacter,
    bool? hasSetSelection,
    bool? hasCopy,
    bool? hasCut,
    bool? hasPaste,
    bool? hasDidGainAccessibilityFocus,
    bool? hasDidLoseAccessibilityFocus,
    bool? hasCustomAction,
    bool? hasDismiss,
    bool? hasMoveCursorForwardByWord,
    bool? hasMoveCursorBackwardByWord,
    bool? hasSetText,

    // Other attributes
    int? maxValueLength,
    int? currentValueLength,
    int? textSelectionBase,
    int? textSelectionExtent,
    int? platformViewId,
    int? scrollChildren,
    int? scrollIndex,
    double? scrollPosition,
    double? scrollExtentMax,
    double? scrollExtentMin,
    double? elevation,
    double? thickness,
    ui.Rect? rect,
    String? label,
    List<ui.StringAttribute>? labelAttributes,
    String? hint,
    List<ui.StringAttribute>? hintAttributes,
    String? value,
    List<ui.StringAttribute>? valueAttributes,
    String? increasedValue,
    List<ui.StringAttribute>? increasedValueAttributes,
    String? decreasedValue,
    List<ui.StringAttribute>? decreasedValueAttributes,
    String? tooltip,
    ui.TextDirection? textDirection,
    Float64List? transform,
    Int32List? additionalActions,
    List<SemanticsNodeUpdate>? children,
  }) {
    // Flags
    if (hasCheckedState == true) {
      flags |= ui.SemanticsFlag.hasCheckedState.index;
    }
    if (isChecked == true) {
      flags |= ui.SemanticsFlag.isChecked.index;
    }
    if (isSelected == true) {
      flags |= ui.SemanticsFlag.isSelected.index;
    }
    if (isButton == true) {
      flags |= ui.SemanticsFlag.isButton.index;
    }
    if (isLink == true) {
      flags |= ui.SemanticsFlag.isLink.index;
    }
    if (isTextField == true) {
      flags |= ui.SemanticsFlag.isTextField.index;
    }
    if (isReadOnly == true) {
      flags |= ui.SemanticsFlag.isReadOnly.index;
    }
    if (isFocusable == true) {
      flags |= ui.SemanticsFlag.isFocusable.index;
    }
    if (isFocused == true) {
      flags |= ui.SemanticsFlag.isFocused.index;
    }
    if (hasEnabledState == true) {
      flags |= ui.SemanticsFlag.hasEnabledState.index;
    }
    if (isEnabled == true) {
      flags |= ui.SemanticsFlag.isEnabled.index;
    }
    if (isInMutuallyExclusiveGroup == true) {
      flags |= ui.SemanticsFlag.isInMutuallyExclusiveGroup.index;
    }
    if (isHeader == true) {
      flags |= ui.SemanticsFlag.isHeader.index;
    }
    if (isObscured == true) {
      flags |= ui.SemanticsFlag.isObscured.index;
    }
    if (scopesRoute == true) {
      flags |= ui.SemanticsFlag.scopesRoute.index;
    }
    if (namesRoute == true) {
      flags |= ui.SemanticsFlag.namesRoute.index;
    }
    if (isHidden == true) {
      flags |= ui.SemanticsFlag.isHidden.index;
    }
    if (isImage == true) {
      flags |= ui.SemanticsFlag.isImage.index;
    }
    if (isLiveRegion == true) {
      flags |= ui.SemanticsFlag.isLiveRegion.index;
    }
    if (hasToggledState == true) {
      flags |= ui.SemanticsFlag.hasToggledState.index;
    }
    if (isToggled == true) {
      flags |= ui.SemanticsFlag.isToggled.index;
    }
    if (hasImplicitScrolling == true) {
      flags |= ui.SemanticsFlag.hasImplicitScrolling.index;
    }
    if (isMultiline == true) {
      flags |= ui.SemanticsFlag.isMultiline.index;
    }
    if (isSlider == true) {
      flags |= ui.SemanticsFlag.isSlider.index;
    }
    if (isKeyboardKey == true) {
      flags |= ui.SemanticsFlag.isKeyboardKey.index;
    }

    // Actions
    if (hasTap == true) {
      actions |= ui.SemanticsAction.tap.index;
    }
    if (hasLongPress == true) {
      actions |= ui.SemanticsAction.longPress.index;
    }
    if (hasScrollLeft == true) {
      actions |= ui.SemanticsAction.scrollLeft.index;
    }
    if (hasScrollRight == true) {
      actions |= ui.SemanticsAction.scrollRight.index;
    }
    if (hasScrollUp == true) {
      actions |= ui.SemanticsAction.scrollUp.index;
    }
    if (hasScrollDown == true) {
      actions |= ui.SemanticsAction.scrollDown.index;
    }
    if (hasIncrease == true) {
      actions |= ui.SemanticsAction.increase.index;
    }
    if (hasDecrease == true) {
      actions |= ui.SemanticsAction.decrease.index;
    }
    if (hasShowOnScreen == true) {
      actions |= ui.SemanticsAction.showOnScreen.index;
    }
    if (hasMoveCursorForwardByCharacter == true) {
      actions |= ui.SemanticsAction.moveCursorForwardByCharacter.index;
    }
    if (hasMoveCursorBackwardByCharacter == true) {
      actions |= ui.SemanticsAction.moveCursorBackwardByCharacter.index;
    }
    if (hasSetSelection == true) {
      actions |= ui.SemanticsAction.setSelection.index;
    }
    if (hasCopy == true) {
      actions |= ui.SemanticsAction.copy.index;
    }
    if (hasCut == true) {
      actions |= ui.SemanticsAction.cut.index;
    }
    if (hasPaste == true) {
      actions |= ui.SemanticsAction.paste.index;
    }
    if (hasDidGainAccessibilityFocus == true) {
      actions |= ui.SemanticsAction.didGainAccessibilityFocus.index;
    }
    if (hasDidLoseAccessibilityFocus == true) {
      actions |= ui.SemanticsAction.didLoseAccessibilityFocus.index;
    }
    if (hasCustomAction == true) {
      actions |= ui.SemanticsAction.customAction.index;
    }
    if (hasDismiss == true) {
      actions |= ui.SemanticsAction.dismiss.index;
    }
    if (hasMoveCursorForwardByWord == true) {
      actions |= ui.SemanticsAction.moveCursorForwardByWord.index;
    }
    if (hasMoveCursorBackwardByWord == true) {
      actions |= ui.SemanticsAction.moveCursorBackwardByWord.index;
    }
    if (hasSetText == true) {
      actions |= ui.SemanticsAction.setText.index;
    }

    // Other attributes
    ui.Rect childRect(SemanticsNodeUpdate child) {
      return transformRect(Matrix4.fromFloat32List(child.transform), child.rect);
    }

    // If a rect is not provided, generate one than covers all children.
    ui.Rect effectiveRect = rect ?? ui.Rect.zero;
    if (children != null && children.isNotEmpty) {
      effectiveRect = childRect(children.first);
      for (final SemanticsNodeUpdate child in children.skip(1)) {
        effectiveRect = effectiveRect.expandToInclude(childRect(child));
      }
    }

    final Int32List childIds = Int32List(children?.length ?? 0);
    if (children != null) {
      for (int i = 0; i < children.length; i++) {
        childIds[i] = children[i].id;
      }
    }

    final SemanticsNodeUpdate update = SemanticsNodeUpdate(
      id: id,
      flags: flags,
      actions: actions,
      maxValueLength: maxValueLength ?? 0,
      currentValueLength: currentValueLength ?? 0,
      textSelectionBase: textSelectionBase ?? 0,
      textSelectionExtent: textSelectionExtent ?? 0,
      platformViewId: platformViewId ?? 0,
      scrollChildren: scrollChildren ?? 0,
      scrollIndex: scrollIndex ?? 0,
      scrollPosition: scrollPosition ?? 0,
      scrollExtentMax: scrollExtentMax ?? 0,
      scrollExtentMin: scrollExtentMin ?? 0,
      rect: effectiveRect,
      label: label ?? '',
      labelAttributes: labelAttributes ?? const <ui.StringAttribute>[],
      hint: hint ?? '',
      hintAttributes: hintAttributes ?? const <ui.StringAttribute>[],
      value: value ?? '',
      valueAttributes: valueAttributes ?? const <ui.StringAttribute>[],
      increasedValue: increasedValue ?? '',
      increasedValueAttributes: increasedValueAttributes ?? const <ui.StringAttribute>[],
      decreasedValue: decreasedValue ?? '',
      decreasedValueAttributes: decreasedValueAttributes ?? const <ui.StringAttribute>[],
      tooltip: tooltip ?? '',
      transform: transform != null ? toMatrix32(transform) : Matrix4.identity().storage,
      elevation: elevation ?? 0,
      thickness: thickness ?? 0,
      childrenInTraversalOrder: childIds,
      childrenInHitTestOrder: childIds,
      additionalActions: additionalActions ?? Int32List(0),
    );
    _nodeUpdates.add(update);
    return update;
  }

  /// Updates the HTML tree from semantics updates accumulated by this builder.
  ///
  /// This builder forgets previous updates and may be reused in future updates.
  Map<int, SemanticsObject> apply() {
    owner.updateSemantics(SemanticsUpdate(nodeUpdates: _nodeUpdates));
    _nodeUpdates.clear();
    return owner.debugSemanticsTree!;
  }

  /// Locates the semantics object with the given [id].
  SemanticsObject getSemanticsObject(int id) {
    return owner.debugSemanticsTree![id]!;
  }

  /// Locates the role manager of the semantics object with the give [id].
  RoleManager? getRoleManager(int id, Role role) {
    return getSemanticsObject(id).debugRoleManagerFor(role);
  }

  /// Locates the [TextField] role manager of the semantics object with the give [id].
  TextField getTextField(int id) {
    return getRoleManager(id, Role.textField)! as TextField;
  }
}

/// Verifies the HTML structure of the current semantics tree.
void expectSemanticsTree(String semanticsHtml) {
  const List<String> ignoredAttributes = <String>['pointer-events'];
  expect(
    canonicalizeHtml(appHostNode.querySelector('flt-semantics')!.outerHtml!, ignoredAttributes: ignoredAttributes),
    canonicalizeHtml(semanticsHtml),
  );
}

/// Finds the first HTML element in the semantics tree used for scrolling.
html.Element? findScrollable() {
  return appHostNode.querySelectorAll('flt-semantics').firstWhereOrNull(
    (html.Element element) {
      return element.style.overflow == 'hidden' ||
        element.style.overflowY == 'scroll' ||
        element.style.overflowX == 'scroll';
    },
  );
}

/// Logs semantics actions dispatched to [ui.window].
class SemanticsActionLogger {
  late StreamController<int> _idLogController;
  late StreamController<ui.SemanticsAction> _actionLogController;

  /// Semantics object ids that dispatched the actions.
  Stream<int> get idLog => _idLog;
  late Stream<int> _idLog;

  /// The actions that were dispatched to [ui.window].
  Stream<ui.SemanticsAction> get actionLog => _actionLog;
  late Stream<ui.SemanticsAction> _actionLog;

  SemanticsActionLogger() {
    _idLogController = StreamController<int>();
    _actionLogController = StreamController<ui.SemanticsAction>();
    _idLog = _idLogController.stream.asBroadcastStream();
    _actionLog = _actionLogController.stream.asBroadcastStream();

    // The browser kicks us out of the test zone when the browser event happens.
    // We memorize the test zone so we can call expect when the callback is
    // fired.
    final Zone testZone = Zone.current;

    ui.window.onSemanticsAction =
        (int id, ui.SemanticsAction action, ByteData? args) {
      _idLogController.add(id);
      _actionLogController.add(action);
      testZone.run(() {
        expect(args, null);
      });
    };
  }
}
