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

// @dart = 2.9

// HACK: pretend to be dart.ui in order to access its internals
library dart.ui;

import 'dart:async';
// this needs to be imported because painting.dart expects it this way
import 'dart:collection' as collection;
import 'dart:convert';
import 'dart:developer' as developer;
import 'dart:math' as math;
import 'dart:nativewrappers'; // ignore: unused_import
import 'dart:typed_data';


// HACK: these parts are to get access to private functions tested here.
part '../../lib/ui/annotations.dart';
part '../../lib/ui/channel_buffers.dart';
part '../../lib/ui/compositing.dart';
part '../../lib/ui/geometry.dart';
part '../../lib/ui/hash_codes.dart';
part '../../lib/ui/hooks.dart';
part '../../lib/ui/lerp.dart';
part '../../lib/ui/natives.dart';
part '../../lib/ui/painting.dart';
part '../../lib/ui/pointer.dart';
part '../../lib/ui/semantics.dart';
part '../../lib/ui/text.dart';
part '../../lib/ui/window.dart';

void main() {
  VoidCallback? originalOnMetricsChanged;
  VoidCallback? originalOnLocaleChanged;
  FrameCallback? originalOnBeginFrame;
  VoidCallback? originalOnDrawFrame;
  TimingsCallback? originalOnReportTimings;
  PointerDataPacketCallback? originalOnPointerDataPacket;
  VoidCallback? originalOnSemanticsEnabledChanged;
  SemanticsActionCallback? originalOnSemanticsAction;
  PlatformMessageCallback? originalOnPlatformMessage;
  VoidCallback? originalOnTextScaleFactorChanged;

  double? oldDPR;
  Size? oldSize;
  double? oldDepth;
  WindowPadding? oldPadding;
  WindowPadding? oldInsets;
  WindowPadding? oldSystemGestureInsets;

  void setUp() {
    oldDPR = window.devicePixelRatio;
    oldSize = window.physicalSize;
    oldDepth = window.physicalDepth;
    oldPadding = window.viewPadding;
    oldInsets = window.viewInsets;
    oldSystemGestureInsets = window.systemGestureInsets;

    originalOnMetricsChanged = window.onMetricsChanged;
    originalOnLocaleChanged = window.onLocaleChanged;
    originalOnBeginFrame = window.onBeginFrame;
    originalOnDrawFrame = window.onDrawFrame;
    originalOnReportTimings = window.onReportTimings;
    originalOnPointerDataPacket = window.onPointerDataPacket;
    originalOnSemanticsEnabledChanged = window.onSemanticsEnabledChanged;
    originalOnSemanticsAction = window.onSemanticsAction;
    originalOnPlatformMessage = window.onPlatformMessage;
    originalOnTextScaleFactorChanged = window.onTextScaleFactorChanged;
  }

  void tearDown() {
    _updateWindowMetrics(
      oldDPR!,                         // DPR
      oldSize!.width,                  // width
      oldSize!.height,                 // height
      oldDepth!,                       // depth
      oldPadding!.top,                 // padding top
      oldPadding!.right,               // padding right
      oldPadding!.bottom,              // padding bottom
      oldPadding!.left,                // padding left
      oldInsets!.top,                  // inset top
      oldInsets!.right,                // inset right
      oldInsets!.bottom,               // inset bottom
      oldInsets!.left,                 // inset left
      oldSystemGestureInsets!.top,     // system gesture inset top
      oldSystemGestureInsets!.right,   // system gesture inset right
      oldSystemGestureInsets!.bottom,  // system gesture inset bottom
      oldSystemGestureInsets!.left,    // system gesture inset left
    );
    window.onMetricsChanged = originalOnMetricsChanged;
    window.onLocaleChanged = originalOnLocaleChanged;
    window.onBeginFrame = originalOnBeginFrame;
    window.onDrawFrame = originalOnDrawFrame;
    window.onReportTimings = originalOnReportTimings;
    window.onPointerDataPacket = originalOnPointerDataPacket;
    window.onSemanticsEnabledChanged = originalOnSemanticsEnabledChanged;
    window.onSemanticsAction = originalOnSemanticsAction;
    window.onPlatformMessage = originalOnPlatformMessage;
    window.onTextScaleFactorChanged = originalOnTextScaleFactorChanged;
  }

  void test(String description, void Function() testFunction) {
    print(description);
    setUp();
    testFunction();
    tearDown();
  }

  void expectEquals(dynamic actual, dynamic expected) {
    if (actual != expected) {
      throw Exception('Equality check failed:\n  Expected: $expected\n  Actual: $actual');
    }
  }

  void expectIterablesEqual(Iterable<dynamic> actual, Iterable<dynamic> expected) {
    expectEquals(actual.length, expected.length);
    final Iterator<dynamic> actualIter = actual.iterator;
    final Iterator<dynamic> expectedIter = expected.iterator;
    while (expectedIter.moveNext()) {
      expectEquals(actualIter.moveNext(), true);
      expectEquals(actualIter.current, expectedIter.current);
    }
    expectEquals(actualIter.moveNext(), false);
  }

  void expectNotEquals(dynamic actual, dynamic expected) {
    if (actual == expected) {
      throw Exception('Inequality check failed:\n  Expected: $expected\n  Actual: $actual');
    }
  }

  void expectIdentical(dynamic actual, dynamic expected) {
    if (!identical(actual, expected)) {
      throw Exception('Identity check failed:\n  Expected: $expected\n  Actual: $actual');
    }
  }

  test('updateUserSettings can handle an empty object', () {
    // this should not throw.
    _updateUserSettingsData('{}');
  });

  test('onMetricsChanged preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;
    late double devicePixelRatio;

    runZoned(() {
      innerZone = Zone.current;
      window.onMetricsChanged = () {
        runZone = Zone.current;
        devicePixelRatio = window.devicePixelRatio;
      };
    });

    window.onMetricsChanged!();
    _updateWindowMetrics(
      0.1234, // DPR
      0.0,    // width
      0.0,    // height
      0.0,    // depth
      0.0,    // padding top
      0.0,    // padding right
      0.0,    // padding bottom
      0.0,    // padding left
      0.0,    // inset top
      0.0,    // inset right
      0.0,    // inset bottom
      0.0,    // inset left
      0.0,    // system gesture inset top
      0.0,    // system gesture inset right
      0.0,    // system gesture inset bottom
      0.0,    // system gesture inset left
    );
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
    expectEquals(devicePixelRatio, 0.1234);
  });

  test('onLocaleChanged preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;
    Locale? locale;

    runZoned(() {
      innerZone = Zone.current;
      window.onLocaleChanged = () {
        runZone = Zone.current;
        locale = window.locale;
      };
    });

    _updateLocales(<String>['en', 'US', '', '']);
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
    expectEquals(locale, const Locale('en', 'US'));
  });

  test('onBeginFrame preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;
    late Duration start;

    runZoned(() {
      innerZone = Zone.current;
      window.onBeginFrame = (Duration value) {
        runZone = Zone.current;
        start = value;
      };
    });

    _beginFrame(1234);
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
    expectEquals(start, const Duration(microseconds: 1234));
  });

  test('onDrawFrame preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;

    runZoned(() {
      innerZone = Zone.current;
      window.onDrawFrame = () {
        runZone = Zone.current;
      };
    });

    _drawFrame();
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
  });

  test('onReportTimings preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;

    window._setNeedsReportTimings = (bool _) {};

    runZoned(() {
      innerZone = Zone.current;
      window.onReportTimings = (List<FrameTiming> timings) {
        runZone = Zone.current;
      };
    });

    _reportTimings(<int>[]);
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
  });

  test('onPointerDataPacket preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;
    late PointerDataPacket data;

    runZoned(() {
      innerZone = Zone.current;
      window.onPointerDataPacket = (PointerDataPacket value) {
        runZone = Zone.current;
        data = value;
      };
    });

    final ByteData testData = ByteData.view(Uint8List(0).buffer);
    _dispatchPointerDataPacket(testData);
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
    expectIterablesEqual(data.data, _unpackPointerDataPacket(testData).data);
  });

  test('onSemanticsEnabledChanged preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;
    late bool enabled;

    runZoned(() {
      innerZone = Zone.current;
      window.onSemanticsEnabledChanged = () {
        runZone = Zone.current;
        enabled = window.semanticsEnabled;
      };
    });

    _updateSemanticsEnabled(window._semanticsEnabled);
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
    expectNotEquals(enabled, null);
    expectEquals(enabled, window._semanticsEnabled);
  });

  test('onSemanticsAction preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;
    late int id;
    late int action;

    runZoned(() {
      innerZone = Zone.current;
      window.onSemanticsAction = (int i, SemanticsAction a, ByteData? _) {
        runZone = Zone.current;
        action = a.index;
        id = i;
      };
    });

    _dispatchSemanticsAction(1234, 4, null);
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
    expectEquals(id, 1234);
    expectEquals(action, 4);
  });

  test('onPlatformMessage preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;
    late String name;

    runZoned(() {
      innerZone = Zone.current;
      window.onPlatformMessage = (String value, _, __) {
        runZone = Zone.current;
        name = value;
      };
    });

    _dispatchPlatformMessage('testName', null, 123456789);
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
    expectEquals(name, 'testName');
  });

  test('onTextScaleFactorChanged preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;
    late double textScaleFactor;

    runZoned(() {
      innerZone = Zone.current;
      window.onTextScaleFactorChanged = () {
        runZone = Zone.current;
        textScaleFactor = window.textScaleFactor;
      };
    });

    window.onTextScaleFactorChanged!();
    _updateTextScaleFactor(0.5);
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
    expectEquals(textScaleFactor, 0.5);
  });

  test('onThemeBrightnessMode preserves callback zone', () {
    late Zone innerZone;
    late Zone runZone;
    late Brightness platformBrightness;

    runZoned(() {
      innerZone = Zone.current;
      window.onPlatformBrightnessChanged = () {
        runZone = Zone.current;
        platformBrightness = window.platformBrightness;
      };
    });

    window.onPlatformBrightnessChanged!();
    _updatePlatformBrightness('dark');
    expectNotEquals(runZone, null);
    expectIdentical(runZone, innerZone);
    expectEquals(platformBrightness, Brightness.dark);
  });

  test('Window padding/insets/viewPadding/systemGestureInsets', () {
    _updateWindowMetrics(
      1.0,   // DPR
      800.0, // width
      600.0, // height
      100.0, // depth
      50.0,  // padding top
      0.0,   // padding right
      40.0,  // padding bottom
      0.0,   // padding left
      0.0,   // inset top
      0.0,   // inset right
      0.0,   // inset bottom
      0.0,   // inset left
      0.0,   // system gesture inset top
      0.0,   // system gesture inset right
      0.0,   // system gesture inset bottom
      0.0,   // system gesture inset left
    );

    expectEquals(window.viewInsets.bottom, 0.0);
    expectEquals(window.viewPadding.bottom, 40.0);
    expectEquals(window.padding.bottom, 40.0);
    expectEquals(window.physicalDepth, 100.0);
    expectEquals(window.systemGestureInsets.bottom, 0.0);

    _updateWindowMetrics(
      1.0,   // DPR
      800.0, // width
      600.0, // height
      100.0, // depth
      50.0,  // padding top
      0.0,   // padding right
      40.0,  // padding bottom
      0.0,   // padding left
      0.0,   // inset top
      0.0,   // inset right
      400.0, // inset bottom
      0.0,   // inset left
      0.0,   // system gesture insets top
      0.0,   // system gesture insets right
      44.0,  // system gesture insets bottom
      0.0,   // system gesture insets left
    );

    expectEquals(window.viewInsets.bottom, 400.0);
    expectEquals(window.viewPadding.bottom, 40.0);
    expectEquals(window.padding.bottom, 0.0);
    expectEquals(window.physicalDepth, 100.0);
    expectEquals(window.systemGestureInsets.bottom, 44.0);
  });
}
