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

import 'dart:async';
import 'dart:ui' as ui;

import 'package:flutter/foundation.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/widgets.dart';

import 'finders.dart';
import 'widget_tester.dart';

/// The result of evaluating a semantics node by a [AccessibilityGuideline].
class Evaluation {
  /// Create a passing evaluation.
  const Evaluation.pass()
      : passed = true,
        reason = null;

  /// Create a failing evaluation, with an optional [reason] explaining the
  /// result.
  const Evaluation.fail([this.reason]) : passed = false;

  // private constructor for adding cases together.
  const Evaluation._(this.passed, this.reason);

  /// Whether the given tree or node passed the policy evaluation.
  final bool passed;

  /// If [passed] is false, contains the reason for failure.
  final String? reason;

  /// Combines two evaluation results.
  ///
  /// The [reason] will be concatenated with a newline, and [passed] will be
  /// combined with an `&&` operator.
  Evaluation operator +(Evaluation? other) {
    if (other == null) {
      return this;
    }

    final StringBuffer buffer = StringBuffer();
    if (reason != null) {
      buffer.write(reason);
      buffer.write(' ');
    }
    if (other.reason != null) {
      buffer.write(other.reason);
    }
    return Evaluation._(
      passed && other.passed,
      buffer.isEmpty ? null : buffer.toString(),
    );
  }
}

/// An accessibility guideline describes a recommendation an application should
/// meet to be considered accessible.
///
/// Use [meetsGuideline] matcher to test whether a screen meets the
/// accessibility guideline.
///
/// {@tool snippet}
///
/// This sample demonstrates how to run an accessibility guideline in a unit
/// test against a single screen.
///
/// ```dart
/// testWidgets('HomePage meets androidTapTargetGuideline', (WidgetTester tester) async {
///   final SemanticsHandle handle = tester.ensureSemantics();
///   await tester.pumpWidget(const MaterialApp(home: HomePage()));
///   await expectLater(tester, meetsGuideline(androidTapTargetGuideline));
///   handle.dispose();
/// });
/// ```
/// {@end-tool}
///
/// See also:
///  * [androidTapTargetGuideline], which checks that tappable nodes have a
///    minimum size of 48 by 48 pixels.
///  * [iOSTapTargetGuideline], which checks that tappable nodes have a minimum
///    size of 44 by 44 pixels.
///  * [textContrastGuideline], which provides guidance for text contrast
///    requirements specified by [WCAG](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html#contrast-ratiodef).
///  * [labeledTapTargetGuideline], which enforces that all nodes with a tap or
///    long press action also have a label.
abstract class AccessibilityGuideline {
  /// A const constructor allows subclasses to be const.
  const AccessibilityGuideline();

  /// Evaluate whether the current state of the `tester` conforms to the rule.
  FutureOr<Evaluation> evaluate(WidgetTester tester);

  /// A description of the policy restrictions and criteria.
  String get description;
}

/// A guideline which enforces that all tappable semantics nodes have a minimum
/// size.
///
/// Each platform defines its own guidelines for minimum tap areas.
///
/// See also:
///  * [AccessibilityGuideline], which provides a general overview of
///    accessibility guidelines and how to use them.
///  * [androidTapTargetGuideline], which checks that tappable nodes have a
///    minimum size of 48 by 48 pixels.
///  * [iOSTapTargetGuideline], which checks that tappable nodes have a minimum
///    size of 44 by 44 pixels.
@visibleForTesting
class MinimumTapTargetGuideline extends AccessibilityGuideline {
  /// Create a new [MinimumTapTargetGuideline].
  const MinimumTapTargetGuideline({required this.size, required this.link});

  /// The minimum allowed size of a tappable node.
  final Size size;

  /// A link describing the tap target guidelines for a platform.
  final String link;

  @override
  FutureOr<Evaluation> evaluate(WidgetTester tester) {
    return _traverse(
      tester,
      tester.binding.pipelineOwner.semanticsOwner!.rootSemanticsNode!,
    );
  }

  Evaluation _traverse(WidgetTester tester, SemanticsNode node) {
    Evaluation result = const Evaluation.pass();
    node.visitChildren((SemanticsNode child) {
      result += _traverse(tester, child);
      return true;
    });
    if (node.isMergedIntoParent) {
      return result;
    }
    if (shouldSkipNode(node)) {
      return result;
    }
    Rect paintBounds = node.rect;
    SemanticsNode? current = node;
    while (current != null) {
      final Matrix4? transform = current.transform;
      if (transform != null) {
        paintBounds = MatrixUtils.transformRect(transform, paintBounds);
      }
      current = current.parent;
    }
    // skip node if it is touching the edge of the screen, since it might
    // be partially scrolled offscreen.
    const double delta = 0.001;
    final Size physicalSize = tester.binding.window.physicalSize;
    if (paintBounds.left <= delta ||
        paintBounds.top <= delta ||
        (paintBounds.bottom - physicalSize.height).abs() <= delta ||
        (paintBounds.right - physicalSize.width).abs() <= delta) {
      return result;
    }
    // shrink by device pixel ratio.
    final Size candidateSize = paintBounds.size / tester.binding.window.devicePixelRatio;
    if (candidateSize.width < size.width - delta ||
        candidateSize.height < size.height - delta) {
      result += Evaluation.fail(
        '$node: expected tap target size of at least $size, '
        'but found $candidateSize\n'
        'See also: $link',
      );
    }
    return result;
  }

  /// Returns whether [SemanticsNode] should be skipped for minimum tap target
  /// guideline.
  ///
  /// Skips nodes which are link, hidden, or do not have actions.
  bool shouldSkipNode(SemanticsNode node) {
    final SemanticsData data = node.getSemanticsData();
    // Skip node if it has no actions, or is marked as hidden.
    if ((!data.hasAction(ui.SemanticsAction.longPress) &&
            !data.hasAction(ui.SemanticsAction.tap)) ||
        data.hasFlag(ui.SemanticsFlag.isHidden)) {
      return true;
    }
    // Skip links https://www.w3.org/WAI/WCAG21/Understanding/target-size.html
    if (data.hasFlag(ui.SemanticsFlag.isLink)) {
      return true;
    }
    return false;
  }

  @override
  String get description => 'Tappable objects should be at least $size';
}

/// A guideline which enforces that all nodes with a tap or long press action
/// also have a label.
///
/// See also:
///  * [AccessibilityGuideline], which provides a general overview of
///    accessibility guidelines and how to use them.
@visibleForTesting
class LabeledTapTargetGuideline extends AccessibilityGuideline {
  const LabeledTapTargetGuideline._();

  @override
  String get description => 'Tappable widgets should have a semantic label';

  @override
  FutureOr<Evaluation> evaluate(WidgetTester tester) {
    final SemanticsNode root = tester.binding.pipelineOwner.semanticsOwner!.rootSemanticsNode!;
    Evaluation traverse(SemanticsNode node) {
      Evaluation result = const Evaluation.pass();
      node.visitChildren((SemanticsNode child) {
        result += traverse(child);
        return true;
      });
      if (node.isMergedIntoParent ||
          node.isInvisible ||
          node.hasFlag(ui.SemanticsFlag.isHidden) ||
          node.hasFlag(ui.SemanticsFlag.isTextField)) {
        return result;
      }
      final SemanticsData data = node.getSemanticsData();
      // Skip node if it has no actions, or is marked as hidden.
      if (!data.hasAction(ui.SemanticsAction.longPress) &&
          !data.hasAction(ui.SemanticsAction.tap)) {
        return result;
      }
      if ((data.label == null || data.label.isEmpty) && (data.tooltip == null || data.tooltip.isEmpty)) {
        result += Evaluation.fail(
          '$node: expected tappable node to have semantic label, '
          'but none was found.\n',
        );
      }
      return result;
    }

    return traverse(root);
  }
}

/// A guideline which verifies that all nodes that contribute semantics via text
/// meet minimum contrast levels.
///
/// The guidelines are defined by the Web Content Accessibility Guidelines,
/// http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html.
///
/// See also:
///  * [AccessibilityGuideline], which provides a general overview of
///    accessibility guidelines and how to use them.
@visibleForTesting
class MinimumTextContrastGuideline extends AccessibilityGuideline {
  /// Create a new [MinimumTextContrastGuideline].
  const MinimumTextContrastGuideline();

  /// The minimum text size considered large for contrast checking.
  ///
  /// Defined by http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html
  static const int kLargeTextMinimumSize = 18;

  /// The minimum text size for bold text to be considered large for contrast
  /// checking.
  ///
  /// Defined by http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html
  static const int kBoldTextMinimumSize = 14;

  /// The minimum contrast ratio for normal text.
  ///
  /// Defined by http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html
  static const double kMinimumRatioNormalText = 4.5;

  /// The minimum contrast ratio for large text.
  ///
  /// Defined by http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html
  static const double kMinimumRatioLargeText = 3.0;

  static const double _kDefaultFontSize = 12.0;

  static const double _tolerance = -0.01;

  @override
  Future<Evaluation> evaluate(WidgetTester tester) async {
    final SemanticsNode root = tester.binding.pipelineOwner.semanticsOwner!.rootSemanticsNode!;
    final RenderView renderView = tester.binding.renderView;
    final OffsetLayer layer = renderView.debugLayer! as OffsetLayer;

    late ui.Image image;
    final ByteData? byteData = await tester.binding.runAsync<ByteData?>(
      () async {
        // Needs to be the same pixel ratio otherwise our dimensions won't match
        // the last transform layer.
        final double ratio = 1 / tester.binding.window.devicePixelRatio;
        image = await layer.toImage(renderView.paintBounds, pixelRatio: ratio);
        return image.toByteData();
      },
    );

    return _evaluateNode(root, tester, image, byteData!);
  }

  Future<Evaluation> _evaluateNode(
    SemanticsNode node,
    WidgetTester tester,
    ui.Image image,
    ByteData byteData,
  ) async {
    Evaluation result = const Evaluation.pass();

    // Skip disabled nodes, as they not required to pass contrast check.
    final bool isDisabled = node.hasFlag(ui.SemanticsFlag.hasEnabledState) &&
        !node.hasFlag(ui.SemanticsFlag.isEnabled);

    if (node.isInvisible ||
        node.isMergedIntoParent ||
        node.hasFlag(ui.SemanticsFlag.isHidden) ||
        isDisabled) {
      return result;
    }

    final SemanticsData data = node.getSemanticsData();
    final List<SemanticsNode> children = <SemanticsNode>[];
    node.visitChildren((SemanticsNode child) {
      children.add(child);
      return true;
    });
    for (final SemanticsNode child in children) {
      result += await _evaluateNode(child, tester, image, byteData);
    }
    if (shouldSkipNode(data)) {
      return result;
    }
    final String text = data.label.isEmpty ? data.value : data.label;
    final Iterable<Element> elements = find.text(text).hitTestable().evaluate();
    for (final Element element in elements) {
      result += await _evaluateElement(node, element, tester, image, byteData);
    }
    return result;
  }

  Future<Evaluation> _evaluateElement(
    SemanticsNode node,
    Element element,
    WidgetTester tester,
    ui.Image image,
    ByteData byteData,
  ) async {
    // Look up inherited text properties to determine text size and weight.
    late bool isBold;
    double? fontSize;

    late final Rect screenBounds;
    late final Rect paintBoundsWithOffset;

    final RenderObject? renderBox = element.renderObject;
    if (renderBox is! RenderBox) {
      throw StateError('Unexpected renderObject type: $renderBox');
    }

    final Matrix4 globalTransform = renderBox.getTransformTo(null);
    paintBoundsWithOffset = MatrixUtils.transformRect(globalTransform, renderBox.paintBounds.inflate(4.0));

    // The semantics node transform will include root view transform, which is
    // not included in renderBox.getTransformTo(null). Manually multiply the
    // root transform to the global transform.
    final Matrix4 rootTransform = Matrix4.identity();
    tester.binding.renderView.applyPaintTransform(tester.binding.renderView.child!, rootTransform);
    rootTransform.multiply(globalTransform);
    screenBounds = MatrixUtils.transformRect(rootTransform, renderBox.paintBounds);
    Rect nodeBounds = node.rect;
    SemanticsNode? current = node;
    while (current != null) {
      final Matrix4? transform = current.transform;
      if (transform != null) {
        nodeBounds = MatrixUtils.transformRect(transform, nodeBounds);
      }
      current = current.parent;
    }
    final Rect intersection = nodeBounds.intersect(screenBounds);
    if (intersection.width <= 0 || intersection.height <= 0) {
      // Skip this element since it doesn't correspond to the given semantic
      // node.
      return const Evaluation.pass();
    }

    final Widget widget = element.widget;
    final DefaultTextStyle defaultTextStyle = DefaultTextStyle.of(element);
    if (widget is Text) {
      final TextStyle? style = widget.style;
      final TextStyle effectiveTextStyle = style == null || style.inherit
          ? defaultTextStyle.style.merge(widget.style)
          : style;
      isBold = effectiveTextStyle.fontWeight == FontWeight.bold;
      fontSize = effectiveTextStyle.fontSize;
    } else if (widget is EditableText) {
      isBold = widget.style.fontWeight == FontWeight.bold;
      fontSize = widget.style.fontSize;
    } else {
      throw StateError('Unexpected widget type: ${widget.runtimeType}');
    }

    if (isNodeOffScreen(paintBoundsWithOffset, tester.binding.window)) {
      return const Evaluation.pass();
    }

    final Map<Color, int> colorHistogram = _colorsWithinRect(byteData, paintBoundsWithOffset, image.width, image.height);

    // Node was too far off screen.
    if (colorHistogram.isEmpty) {
      return const Evaluation.pass();
    }

    final _ContrastReport report = _ContrastReport(colorHistogram);

    final double contrastRatio = report.contrastRatio();
    final double targetContrastRatio = this.targetContrastRatio(fontSize, bold: isBold);

    if (contrastRatio - targetContrastRatio >= _tolerance) {
      return const Evaluation.pass();
    }
    return Evaluation.fail(
      '$node:\n'
      'Expected contrast ratio of at least $targetContrastRatio '
      'but found ${contrastRatio.toStringAsFixed(2)} '
      'for a font size of $fontSize.\n'
      'The computed colors was:\n'
      'light - ${report.lightColor}, dark - ${report.darkColor}\n'
      'See also: '
      'https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html',
    );
  }

  /// Returns whether node should be skipped.
  ///
  /// Skip routes which might have labels, and nodes without any text.
  bool shouldSkipNode(SemanticsData data) =>
      data.hasFlag(ui.SemanticsFlag.scopesRoute) ||
      (data.label.trim().isEmpty && data.value.trim().isEmpty);

  /// Returns if a rectangle of node is off the screen.
  ///
  /// Allows node to be of screen partially before culling the node.
  bool isNodeOffScreen(Rect paintBounds, ui.FlutterView window) {
    final Size windowPhysicalSize = window.physicalSize * window.devicePixelRatio;
    return paintBounds.top < -50.0 ||
           paintBounds.left < -50.0 ||
           paintBounds.bottom > windowPhysicalSize.height + 50.0 ||
           paintBounds.right > windowPhysicalSize.width + 50.0;
  }

  /// Returns the required contrast ratio for the [fontSize] and [bold] setting.
  ///
  /// Defined by http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html
  double targetContrastRatio(double? fontSize, {required bool bold}) {
    final double fontSizeOrDefault = fontSize ?? _kDefaultFontSize;
    if ((bold && fontSizeOrDefault >= kBoldTextMinimumSize) ||
        fontSizeOrDefault >= kLargeTextMinimumSize) {
      return kMinimumRatioLargeText;
    }
    return kMinimumRatioNormalText;
  }

  @override
  String get description => 'Text contrast should follow WCAG guidelines';
}

/// A guideline which verifies that all elements specified by [finder]
/// meet minimum contrast levels.
///
/// See also:
///  * [AccessibilityGuideline], which provides a general overview of
///    accessibility guidelines and how to use them.
class CustomMinimumContrastGuideline extends AccessibilityGuideline {
  /// Creates a custom guideline which verifies that all elements specified
  /// by [finder] meet minimum contrast levels.
  ///
  /// An optional description string can be given using the [description] parameter.
  const CustomMinimumContrastGuideline({
    required this.finder,
    this.minimumRatio = 4.5,
    this.tolerance = 0.01,
    String description = 'Contrast should follow custom guidelines',
  }) : _description = description;

  /// The minimum contrast ratio allowed.
  ///
  /// Defaults to 4.5, the minimum contrast
  /// ratio for normal text, defined by WCAG.
  /// See http://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html.
  final double minimumRatio;

  /// Tolerance for minimum contrast ratio.
  ///
  /// Any contrast ratio greater than [minimumRatio] or within a distance of [tolerance]
  /// from [minimumRatio] passes the test.
  /// Defaults to 0.01.
  final double tolerance;

  /// The [Finder] used to find a subset of elements.
  ///
  /// [finder] determines which subset of elements will be tested for
  /// contrast ratio.
  final Finder finder;

  final String _description;

  @override
  String get description => _description;

  @override
  Future<Evaluation> evaluate(WidgetTester tester) async {
    // Compute elements to be evaluated.

    final List<Element> elements = finder.evaluate().toList();

    // Obtain rendered image.

    final RenderView renderView = tester.binding.renderView;
    final OffsetLayer layer = renderView.debugLayer! as OffsetLayer;
    late ui.Image image;
    final ByteData? byteData = await tester.binding.runAsync<ByteData?>(
      () async {
        // Needs to be the same pixel ratio otherwise our dimensions won't match
        // the last transform layer.
        final double ratio = 1 / tester.binding.window.devicePixelRatio;
        image = await layer.toImage(renderView.paintBounds, pixelRatio: ratio);
        return image.toByteData();
      },
    );

    // How to evaluate a single element.

    Evaluation evaluateElement(Element element) {
      final RenderBox renderObject = element.renderObject! as RenderBox;

      final Rect originalPaintBounds = renderObject.paintBounds;

      final Rect inflatedPaintBounds = originalPaintBounds.inflate(4.0);

      final Rect paintBounds = Rect.fromPoints(
        renderObject.localToGlobal(inflatedPaintBounds.topLeft),
        renderObject.localToGlobal(inflatedPaintBounds.bottomRight),
      );

      final Map<Color, int> colorHistogram = _colorsWithinRect(byteData!, paintBounds, image.width, image.height);

      if (colorHistogram.isEmpty) {
        return const Evaluation.pass();
      }

      final _ContrastReport report = _ContrastReport(colorHistogram);
      final double contrastRatio = report.contrastRatio();

      if (contrastRatio >= minimumRatio - tolerance) {
        return const Evaluation.pass();
      } else {
        return Evaluation.fail(
          '$element:\nExpected contrast ratio of at least '
          '$minimumRatio but found ${contrastRatio.toStringAsFixed(2)} \n'
          'The computed light color was: ${report.lightColor}, '
          'The computed dark color was: ${report.darkColor}\n'
          '$description',
        );
      }
    }

    // Collate all evaluations into a final evaluation, then return.

    Evaluation result = const Evaluation.pass();

    for (final Element element in elements) {
      result = result + evaluateElement(element);
    }

    return result;
  }
}

/// A class that reports the contrast ratio of a part of the screen.
///
/// Commonly used in accessibility testing to obtain the contrast ratio of
/// text widgets and other types of widgets.
class _ContrastReport {
  /// Generates a contrast report given a color histogram.
  ///
  /// The contrast ratio of the most frequent light color and the most
  /// frequent dark color is calculated. Colors are divided into light and
  /// dark colors based on their lightness as an [HSLColor].
  factory _ContrastReport(Map<Color, int> colorHistogram) {
    // To determine the lighter and darker color, partition the colors
    // by HSL lightness and then choose the mode from each group.
    double totalLightness = 0.0;
    int count = 0;
    for (final MapEntry<Color, int> entry in colorHistogram.entries) {
      totalLightness += HSLColor.fromColor(entry.key).lightness * entry.value;
      count += entry.value;
    }
    final double averageLightness = totalLightness / count;
    assert(!averageLightness.isNaN);

    MapEntry<Color, int>? lightColor;
    MapEntry<Color, int>? darkColor;

    // Find the most frequently occurring light and dark color.
    for (final MapEntry<Color, int> entry in colorHistogram.entries) {
      final double lightness = HSLColor.fromColor(entry.key).lightness;
      final int count = entry.value;
      if (lightness <= averageLightness) {
        if (count > (darkColor?.value ?? 0)) {
          darkColor = entry;
        }
      } else if (count > (lightColor?.value ?? 0)) {
        lightColor = entry;
      }
    }

    // If there is only single color, it is reported as both dark and light.
    return _ContrastReport._(
      lightColor?.key ?? darkColor!.key,
      darkColor?.key ?? lightColor!.key,
    );
  }

  const _ContrastReport._(this.lightColor, this.darkColor);

  /// The most frequently occurring light color. Uses [Colors.transparent] if
  /// the rectangle is empty.
  final Color lightColor;

  /// The most frequently occurring dark color. Uses [Colors.transparent] if
  /// the rectangle is empty.
  final Color darkColor;

  /// Computes the contrast ratio as defined by the WCAG.
  ///
  /// Source: https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html
  double contrastRatio() => (lightColor.computeLuminance() + 0.05) / (darkColor.computeLuminance() + 0.05);
}

/// Gives the color histogram of all pixels inside a given rectangle on the
/// screen.
///
/// Given a [ByteData] object [data], which stores the color of each pixel
/// in row-first order, where each pixel is given in 4 bytes in RGBA order,
/// and [paintBounds], the rectangle, and [width] and [height],
//  the dimensions of the [ByteData] returns color histogram.
Map<Color, int> _colorsWithinRect(
    ByteData data,
    Rect paintBounds,
    int width,
    int height,
) {
  final Rect truePaintBounds = paintBounds.intersect(Rect.fromLTWH(0.0, 0.0, width.toDouble(), height.toDouble()));

  final int leftX = truePaintBounds.left.floor();
  final int rightX = truePaintBounds.right.ceil();
  final int topY = truePaintBounds.top.floor();
  final int bottomY = truePaintBounds.bottom.ceil();

  final Map<int, int> rgbaToCount = <int, int>{};

  int getPixel(ByteData data, int x, int y) {
    final int offset = (y * width + x) * 4;
    return data.getUint32(offset);
  }

  for (int x = leftX; x < rightX; x++) {
    for (int y = topY; y < bottomY; y++) {
      rgbaToCount.update(
        getPixel(data, x, y),
        (int count) => count + 1,
        ifAbsent: () => 1,
      );
    }
  }

  return rgbaToCount.map<Color, int>((int rgba, int count) {
    final int argb =  (rgba << 24) | (rgba >> 8) & 0xFFFFFFFF;
    return MapEntry<Color, int>(Color(argb), count);
  });
}

/// A guideline which requires tappable semantic nodes a minimum size of
/// 48 by 48.
///
/// See also:
///
///  * [Android tap target guidelines](https://support.google.com/accessibility/android/answer/7101858?hl=en).
///  * [AccessibilityGuideline], which provides a general overview of
///    accessibility guidelines and how to use them.
///  * [iOSTapTargetGuideline], which checks that tappable nodes have a minimum
///    size of 44 by 44 pixels.
const AccessibilityGuideline androidTapTargetGuideline = MinimumTapTargetGuideline(
  size: Size(48.0, 48.0),
  link: 'https://support.google.com/accessibility/android/answer/7101858?hl=en',
);

/// A guideline which requires tappable semantic nodes a minimum size of
/// 44 by 44.
///
/// See also:
///
///  * [iOS human interface guidelines](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/adaptivity-and-layout/).
///  * [AccessibilityGuideline], which provides a general overview of
///    accessibility guidelines and how to use them.
///  * [androidTapTargetGuideline], which checks that tappable nodes have a
///    minimum size of 48 by 48 pixels.
const AccessibilityGuideline iOSTapTargetGuideline = MinimumTapTargetGuideline(
  size: Size(44.0, 44.0),
  link: 'https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/adaptivity-and-layout/',
);

/// A guideline which requires text contrast to meet minimum values.
///
/// This guideline traverses the semantics tree looking for nodes with values or
/// labels that corresponds to a Text or Editable text widget. Given the
/// background pixels for the area around this widget, it performs a very naive
/// partitioning of the colors into "light" and "dark" and then chooses the most
/// frequently occurring color in each partition as a representative of the
/// foreground and background colors. The contrast ratio is calculated from
/// these colors according to the [WCAG](https://www.w3.org/TR/UNDERSTANDING-WCAG20/visual-audio-contrast-contrast.html#contrast-ratiodef)
///
///  * [AccessibilityGuideline], which provides a general overview of
///    accessibility guidelines and how to use them.
const AccessibilityGuideline textContrastGuideline = MinimumTextContrastGuideline();

/// A guideline which enforces that all nodes with a tap or long press action
/// also have a label.
///
///  * [AccessibilityGuideline], which provides a general overview of
///    accessibility guidelines and how to use them.
const AccessibilityGuideline labeledTapTargetGuideline = LabeledTapTargetGuideline._();
