// Copyright 2014 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.

// ignore_for_file: avoid_dynamic_calls

import 'dart:convert';

import 'package:meta/meta.dart';

import 'constants.dart';

/// A semantics node created from Android accessibility information.
///
/// This object represents Android accessibility information derived from an
/// [AccessibilityNodeInfo](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo)
/// object. The purpose is to verify in integration
/// tests that our semantics framework produces the correct accessibility info
/// on Android.
///
/// See also:
///
///   * [AccessibilityNodeInfo](https://developer.android.com/reference/android/view/accessibility/AccessibilityNodeInfo)
class AndroidSemanticsNode {
  AndroidSemanticsNode._(this._values);

  /// Deserializes a new [AndroidSemanticsNode] from a json map.
  ///
  /// The structure of the JSON:
  ///
  ///     {
  ///       "flags": {
  ///         "isChecked": bool,
  ///         "isCheckable": bool,
  ///         "isEditable": bool,
  ///         "isEnabled": bool,
  ///         "isFocusable": bool,
  ///         "isFocused": bool,
  ///         "isHeading": bool,
  ///         "isPassword": bool,
  ///         "isLongClickable": bool,
  ///       },
  ///       "text": String,
  ///       "contentDescription": String,
  ///       "className": String,
  ///       "id": int,
  ///       "rect": {
  ///         left: int,
  ///         top: int,
  ///         right: int,
  ///         bottom: int,
  ///       },
  ///       actions: [
  ///         int,
  ///       ]
  ///     }
  factory AndroidSemanticsNode.deserialize(String value) {
    return AndroidSemanticsNode._(json.decode(value));
  }

  final dynamic _values;
  final List<AndroidSemanticsNode> _children = <AndroidSemanticsNode>[];

  dynamic get _flags => _values['flags'];

  /// The text value of the semantics node.
  ///
  /// This is produced by combining the value, label, and hint fields from
  /// the Flutter [SemanticsNode].
  String? get text => _values['text'] as String?;

  /// The contentDescription of the semantics node.
  ///
  /// This field is used for the Switch, Radio, and Checkbox widgets
  /// instead of [text]. If the text property is used for these, TalkBack
  /// will not read out the "checked" or "not checked" label by default.
  ///
  /// This is produced by combining the value, label, and hint fields from
  /// the Flutter [SemanticsNode].
  String? get contentDescription => _values['contentDescription'] as String?;

  /// The className of the semantics node.
  ///
  /// Certain kinds of Flutter semantics are mapped to Android classes to
  /// use their default semantic behavior, such as checkboxes and images.
  ///
  /// If a more specific value isn't provided, it defaults to
  /// "android.view.View".
  String? get className => _values['className'] as String?;

  /// The identifier for this semantics node.
  int? get id => _values['id'] as int?;

  /// The children of this semantics node.
  List<AndroidSemanticsNode> get children => _children;

  /// Whether the node is currently in a checked state.
  ///
  /// Equivalent to [SemanticsFlag.isChecked].
  bool? get isChecked => _flags['isChecked'] as bool?;

  /// Whether the node can be in a checked state.
  ///
  /// Equivalent to [SemanticsFlag.hasCheckedState]
  bool? get isCheckable => _flags['isCheckable'] as bool?;

  /// Whether the node is editable.
  ///
  /// This is usually only applied to text fields, which map
  /// to "android.widget.EditText".
  bool? get isEditable => _flags['isEditable'] as bool?;

  /// Whether the node is enabled.
  bool? get isEnabled => _flags['isEnabled'] as bool?;

  /// Whether the node is focusable.
  bool? get isFocusable => _flags['isFocusable'] as bool?;

  /// Whether the node is focused.
  bool? get isFocused => _flags['isFocused'] as bool?;

  /// Whether the node is considered a heading.
  bool? get isHeading => _flags['isHeading'] as bool?;

  /// Whether the node represents a password field.
  ///
  /// Equivalent to [SemanticsFlag.isObscured].
  bool? get isPassword => _flags['isPassword'] as bool?;

  /// Whether the node is long clickable.
  ///
  /// Equivalent to having [SemanticsAction.longPress].
  bool? get isLongClickable => _flags['isLongClickable'] as bool?;

  /// Gets a [Rect] which defines the position and size of the semantics node.
  Rect getRect() {
    final dynamic rawRect = _values['rect'];
    if (rawRect == null) {
      return const Rect.fromLTRB(0.0, 0.0, 0.0, 0.0);
    }
    return Rect.fromLTRB(
      (rawRect['left']! as int).toDouble(),
      (rawRect['top']! as int).toDouble(),
      (rawRect['right']! as int).toDouble(),
      (rawRect['bottom']! as int).toDouble(),
    );
  }

  /// Gets a [Size] which defines the size of the semantics node.
  Size getSize() {
    final Rect rect = getRect();
    return Size(rect.bottom - rect.top, rect.right - rect.left);
  }

  /// Gets a list of [AndroidSemanticsActions] which are defined for the node.
  List<AndroidSemanticsAction> getActions() {
    final List<int>? actions = (_values['actions'] as List<dynamic>?)?.cast<int>();
    if (actions == null) {
      return const <AndroidSemanticsAction>[];
    }
    final List<AndroidSemanticsAction> convertedActions = <AndroidSemanticsAction>[];
    for (final int id in actions) {
      final AndroidSemanticsAction? action = AndroidSemanticsAction.deserialize(id);
      if (action != null) {
        convertedActions.add(action);
      }
    }
    return convertedActions;
  }

  @override
  String toString() {
    return _values.toString();
  }
}


/// A Dart VM implementation of a rectangle.
///
/// Created to mirror the implementation of [ui.Rect].
@immutable
class Rect {
  /// Creates a new rectangle.
  ///
  /// All values are required.
  const Rect.fromLTRB(this.left, this.top, this.right, this.bottom);

  /// The top side of the rectangle.
  final double top;

  /// The left side of the rectangle.
  final double left;

  /// The right side of the rectangle.
  final double right;

  /// The bottom side of the rectangle.
  final double bottom;

  @override
  int get hashCode => Object.hash(top, left, right, bottom);

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is Rect
        && other.top == top
        && other.left == left
        && other.right == right
        && other.bottom == bottom;
  }

  @override
  String toString() => 'Rect.fromLTRB($left, $top, $right, $bottom)';
}

/// A Dart VM implementation of a Size.
///
/// Created to mirror the implementation [ui.Size].
@immutable
class Size {
  /// Creates a new [Size] object.
  const Size(this.width, this.height);

  /// The width of some object.
  final double width;

  /// The height of some object.
  final double height;

  @override
  int get hashCode => Object.hash(width, height);

  @override
  bool operator ==(Object other) {
    if (other.runtimeType != runtimeType) {
      return false;
    }
    return other is Size
        && other.width == width
        && other.height == height;
  }

  @override
  String toString() => 'Size{$width, $height}';
}
