// 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:convert';
import 'dart:io';
import 'dart:ui';

import 'package:flutter/foundation.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';

import 'package:flutter_test/flutter_test.dart';

const String license1 = '''
L1Package1
L1Package2
L1Package3

L1Paragraph1

L1Paragraph2

L1Paragraph3''';

const String license2 = '''
L2Package1
L2Package2
L2Package3

L2Paragraph1

L2Paragraph2

L2Paragraph3''';

const String combinedLicenses =
    '''
$license1
--------------------------------------------------------------------------------
$license2
''';

class TestBinding extends BindingBase with SchedulerBinding, ServicesBinding {
  ViewFocusEvent? lastFocusEvent;

  @override
  TestDefaultBinaryMessenger get defaultBinaryMessenger =>
      super.defaultBinaryMessenger as TestDefaultBinaryMessenger;

  @override
  TestDefaultBinaryMessenger createBinaryMessenger() {
    Future<ByteData?> keyboardHandler(ByteData? message) async {
      return const StandardMethodCodec().encodeSuccessEnvelope(<int, int>{1: 1});
    }

    return TestDefaultBinaryMessenger(
      super.createBinaryMessenger(),
      outboundHandlers: <String, MessageHandler>{'flutter/keyboard': keyboardHandler},
    );
  }

  @override
  void handleViewFocusChanged(ViewFocusEvent event) {
    super.handleViewFocusChanged(event);
    lastFocusEvent = event;
  }
}

void main() {
  final binding = TestBinding();

  test('Adds rootBundle LICENSES to LicenseRegistry', () async {
    binding.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (
      ByteData? message,
    ) async {
      if (const StringCodec().decodeMessage(message) == 'NOTICES.Z' && !kIsWeb) {
        return Uint8List.fromList(gzip.encode(utf8.encode(combinedLicenses))).buffer.asByteData();
      }
      if (const StringCodec().decodeMessage(message) == 'NOTICES' && kIsWeb) {
        return const StringCodec().encodeMessage(combinedLicenses);
      }
      return null;
    });

    final List<LicenseEntry> licenses = await LicenseRegistry.licenses.toList();

    expect(licenses[0].packages, equals(<String>['L1Package1', 'L1Package2', 'L1Package3']));
    expect(
      licenses[0].paragraphs.map((LicenseParagraph p) => p.text),
      equals(<String>['L1Paragraph1', 'L1Paragraph2', 'L1Paragraph3']),
    );

    expect(licenses[1].packages, equals(<String>['L2Package1', 'L2Package2', 'L2Package3']));
    expect(
      licenses[1].paragraphs.map((LicenseParagraph p) => p.text),
      equals(<String>['L2Paragraph1', 'L2Paragraph2', 'L2Paragraph3']),
    );
  });

  test('didHaveMemoryPressure clears asset caches', () async {
    var flutterAssetsCallCount = 0;
    binding.defaultBinaryMessenger.setMockMessageHandler('flutter/assets', (
      ByteData? message,
    ) async {
      flutterAssetsCallCount += 1;
      return ByteData.sublistView(utf8.encode('test_asset_data'));
    });

    await rootBundle.loadString('test_asset');
    expect(flutterAssetsCallCount, 1);
    await rootBundle.loadString('test_asset2');
    expect(flutterAssetsCallCount, 2);
    await rootBundle.loadString('test_asset');
    expect(flutterAssetsCallCount, 2);
    await rootBundle.loadString('test_asset2');
    expect(flutterAssetsCallCount, 2);

    final ByteData message = const JSONMessageCodec().encodeMessage(<String, dynamic>{
      'type': 'memoryPressure',
    })!;
    await binding.defaultBinaryMessenger.handlePlatformMessage('flutter/system', message, (_) {});

    await rootBundle.loadString('test_asset');
    expect(flutterAssetsCallCount, 3);
    await rootBundle.loadString('test_asset2');
    expect(flutterAssetsCallCount, 4);
    await rootBundle.loadString('test_asset');
    expect(flutterAssetsCallCount, 4);
    await rootBundle.loadString('test_asset2');
    expect(flutterAssetsCallCount, 4);
  });

  test('initInstances sets a default method call handler for SystemChannels.textInput', () async {
    final ByteData message = const JSONMessageCodec().encodeMessage(<String, dynamic>{
      'method': 'TextInput.requestElementsInRect',
      'args': null,
    })!;
    await binding.defaultBinaryMessenger.handlePlatformMessage('flutter/textinput', message, (
      ByteData? data,
    ) {
      expect(data, isNotNull);
    });
  });

  test('Calling exitApplication sends a method call to the engine', () async {
    var sentMessage = false;
    MethodCall? methodCall;
    binding.defaultBinaryMessenger.setMockMessageHandler('flutter/platform', (
      ByteData? message,
    ) async {
      methodCall = const JSONMethodCodec().decodeMethodCall(message);
      sentMessage = true;
      return const JSONMethodCodec().encodeSuccessEnvelope(<String, String>{'response': 'cancel'});
    });
    final AppExitResponse response = await binding.exitApplication(AppExitType.required);
    expect(sentMessage, isTrue);
    expect(methodCall, isNotNull);
    expect((methodCall!.arguments as Map<String, dynamic>)['type'], equals('required'));
    expect(response, equals(AppExitResponse.cancel));
  });

  test('Default handleRequestAppExit returns exit', () async {
    const incomingCall = MethodCall('System.requestAppExit', <dynamic>[
      <String, dynamic>{'type': 'cancelable'},
    ]);
    var receivedReply = false;
    Map<String, dynamic>? result;
    await binding.defaultBinaryMessenger.handlePlatformMessage(
      'flutter/platform',
      const JSONMethodCodec().encodeMethodCall(incomingCall),
      (ByteData? message) async {
        result =
            (const JSONMessageCodec().decodeMessage(message) as List<dynamic>)[0]
                as Map<String, dynamic>;
        receivedReply = true;
      },
    );

    expect(receivedReply, isTrue);
    expect(result, isNotNull);
    expect(result!['response'], equals('exit'));
  });

  test('initInstances synchronizes keyboard state', () async {
    final Set<PhysicalKeyboardKey> physicalKeys = HardwareKeyboard.instance.physicalKeysPressed;
    final Set<LogicalKeyboardKey> logicalKeys = HardwareKeyboard.instance.logicalKeysPressed;

    expect(physicalKeys.length, 1);
    expect(logicalKeys.length, 1);
    expect(physicalKeys.first, const PhysicalKeyboardKey(1));
    expect(logicalKeys.first, const LogicalKeyboardKey(1));
  });

  test('Default handleViewFocusChanged propagates event', () async {
    const event = ViewFocusEvent(
      viewId: 0,
      direction: ViewFocusDirection.forward,
      state: ViewFocusState.focused,
    );
    PlatformDispatcher.instance.onViewFocusChange?.call(event);
    expect(binding.lastFocusEvent, equals(event));
  });
}
