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

// HACK: pretend to be dart.ui in order to access its internals
// @dart = 2.6
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';


import 'package:test/test.dart';

// 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() {
  group('window callback zones', () {
    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;

    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;
    });

    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;
    });

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

    test('onMetricsChanged preserves callback zone', () {
      Zone innerZone;
      Zone runZone;
      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
      );
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
      expect(devicePixelRatio, equals(0.1234));
    });

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

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

      _updateLocales(<String>['en', 'US', '', '']);
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
      expect(locale, equals(const Locale('en', 'US')));
    });

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

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

      _beginFrame(1234);
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
      expect(start, equals(const Duration(microseconds: 1234)));
    });

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

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

      _drawFrame();
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
    });

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

      window._setNeedsReportTimings = (bool _) {};

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

      _reportTimings(<int>[]);
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
    });

    test('onPointerDataPacket preserves callback zone', () {
      Zone innerZone;
      Zone runZone;
      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);
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
      expect(data.data, equals(_unpackPointerDataPacket(testData).data));
    });

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

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

      _updateSemanticsEnabled(window._semanticsEnabled);
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
      expect(enabled, isNotNull);
      expect(enabled, equals(window._semanticsEnabled));
    });

    test('onSemanticsAction preserves callback zone', () {
      Zone innerZone;
      Zone runZone;
      int id;
      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);
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
      expect(id, equals(1234));
      expect(action, equals(4));
    });

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

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

      _dispatchPlatformMessage('testName', null, null);
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
      expect(name, equals('testName'));
    });

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

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

      window.onTextScaleFactorChanged();
      _updateTextScaleFactor(0.5);
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
      expect(textScaleFactor, equals(0.5));
    });

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

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

      window.onPlatformBrightnessChanged();
      _updatePlatformBrightness('dark');
      expect(runZone, isNotNull);
      expect(runZone, same(innerZone));
      expect(platformBrightness, equals(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
      );

      expect(window.viewInsets.bottom, 0.0);
      expect(window.viewPadding.bottom, 40.0);
      expect(window.padding.bottom, 40.0);
      expect(window.physicalDepth, 100.0);
      expect(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
      );

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