// 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 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/src/foundation/diagnostics.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
  TestWidgetsFlutterBinding.ensureInitialized();

  late FakeMenuChannel fakeMenuChannel;
  late PlatformMenuDelegate originalDelegate;
  late DefaultPlatformMenuDelegate delegate;
  final List<String> activated = <String>[];
  final List<String> opened = <String>[];
  final List<String> closed = <String>[];

  void onActivate(String item) {
    activated.add(item);
  }

  void onOpen(String item) {
    opened.add(item);
  }

  void onClose(String item) {
    closed.add(item);
  }

  setUp(() {
    fakeMenuChannel = FakeMenuChannel((MethodCall call) async {});
    delegate = DefaultPlatformMenuDelegate(channel: fakeMenuChannel);
    originalDelegate = WidgetsBinding.instance.platformMenuDelegate;
    WidgetsBinding.instance.platformMenuDelegate = delegate;
    activated.clear();
    opened.clear();
    closed.clear();
  });

  tearDown(() {
    WidgetsBinding.instance.platformMenuDelegate = originalDelegate;
  });

  group('PlatformMenuBar', () {
    testWidgets('basic menu structure is transmitted to platform', (WidgetTester tester) async {
      await tester.pumpWidget(
        MaterialApp(
          home: Material(
            child: PlatformMenuBar(
              menus: createTestMenus(
                onActivate: onActivate,
                onOpen: onOpen,
                onClose: onClose,
                shortcuts: <String, MenuSerializableShortcut>{
                  subSubMenu10[0]: const SingleActivator(LogicalKeyboardKey.keyA, control: true),
                  subSubMenu10[1]: const SingleActivator(LogicalKeyboardKey.keyB, shift: true),
                  subSubMenu10[2]: const SingleActivator(LogicalKeyboardKey.keyC, alt: true),
                  subSubMenu10[3]: const SingleActivator(LogicalKeyboardKey.keyD, meta: true),
                },
              ),
              child: const Center(child: Text('Body')),
            ),
          ),
        ),
      );

      expect(fakeMenuChannel.outgoingCalls.last.method, equals('Menu.setMenus'));
      expect(
        fakeMenuChannel.outgoingCalls.last.arguments,
        equals(<String, Object?>{
          '0': <Map<String, Object?>>[
            <String, Object?>{
              'id': 2,
              'label': 'Menu 0',
              'enabled': true,
              'children': <Map<String, Object?>>[
                <String, Object?>{
                  'id': 1,
                  'label': 'Sub Menu 00',
                  'enabled': true,
                },
              ],
            },
            <String, Object?>{
              'id': 18,
              'label': 'Menu 1',
              'enabled': true,
              'children': <Map<String, Object?>>[
                <String, Object?>{
                  'id': 4,
                  'label': 'Sub Menu 10',
                  'enabled': true,
                },
                <String, Object?>{'id': 5, 'isDivider': true},
                <String, Object?>{
                  'id': 16,
                  'label': 'Sub Menu 11',
                  'enabled': true,
                  'children': <Map<String, Object?>>[
                    <String, Object?>{
                      'id': 7,
                      'label': 'Sub Sub Menu 110',
                      'enabled': true,
                      'shortcutTrigger': 97,
                      'shortcutModifiers': 8,
                    },
                    <String, Object?>{'id': 8, 'isDivider': true},
                    <String, Object?>{
                      'id': 10,
                      'label': 'Sub Sub Menu 111',
                      'enabled': true,
                      'shortcutTrigger': 98,
                      'shortcutModifiers': 2,
                    },
                    <String, Object?>{'id': 11, 'isDivider': true},
                    <String, Object?>{
                      'id': 12,
                      'label': 'Sub Sub Menu 112',
                      'enabled': true,
                      'shortcutTrigger': 99,
                      'shortcutModifiers': 4,
                    },
                    <String, Object?>{'id': 13, 'isDivider': true},
                    <String, Object?>{
                      'id': 14,
                      'label': 'Sub Sub Menu 113',
                      'enabled': true,
                      'shortcutTrigger': 100,
                      'shortcutModifiers': 1,
                    },
                  ],
                },
                <String, Object?>{
                  'id': 17,
                  'label': 'Sub Menu 12',
                  'enabled': true,
                },
              ],
            },
            <String, Object?>{
              'id': 20,
              'label': 'Menu 2',
              'enabled': true,
              'children': <Map<String, Object?>>[
                <String, Object?>{
                  'id': 19,
                  'label': 'Sub Menu 20',
                  'enabled': false,
                },
              ],
            },
            <String, Object?>{'id': 21, 'label': 'Menu 3', 'enabled': false, 'children': <Map<String, Object?>>[]},
          ],
        }),
      );
    });
    testWidgets('asserts when more than one has locked the delegate', (WidgetTester tester) async {
      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: PlatformMenuBar(
              menus: <PlatformMenuItem>[],
              child: PlatformMenuBar(
                menus: <PlatformMenuItem>[],
                child: SizedBox(),
              ),
            ),
          ),
        ),
      );
      expect(tester.takeException(), isA<AssertionError>());
    });
    testWidgets('diagnostics', (WidgetTester tester) async {
      const PlatformMenuItem item = PlatformMenuItem(
        label: 'label2',
        shortcut: SingleActivator(LogicalKeyboardKey.keyA),
      );
      const PlatformMenuBar menuBar = PlatformMenuBar(
        menus: <PlatformMenuItem>[item],
        child: SizedBox(),
      );

      await tester.pumpWidget(
        const MaterialApp(
          home: Material(
            child: menuBar,
          ),
        ),
      );
      await tester.pump();

      expect(
        menuBar.toStringDeep(),
        equalsIgnoringHashCodes(
          'PlatformMenuBar#00000\n'
          ' └─PlatformMenuItem#00000(label2)\n'
          '     label: "label2"\n'
          '     shortcut: SingleActivator#00000(keys: Key A)\n'
          '     DISABLED\n',
        ),
      );
    });
  });
  group('MenuBarItem', () {
    testWidgets('diagnostics', (WidgetTester tester) async {
      const PlatformMenuItem childItem = PlatformMenuItem(
        label: 'label',
      );
      const PlatformMenu item = PlatformMenu(
        label: 'label',
        menus: <PlatformMenuItem>[childItem],
      );

      final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder();
      item.debugFillProperties(builder);

      final List<String> description = builder.properties
          .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
          .map((DiagnosticsNode node) => node.toString())
          .toList();

      expect(description, <String>[
        'label: "label"',
      ]);
    });
  });

  group('ShortcutSerialization', () {
    testWidgets('character constructor', (WidgetTester tester) async {
      final ShortcutSerialization serialization = ShortcutSerialization.character('?');
      expect(serialization.toChannelRepresentation(), equals(<String, Object?>{
        'shortcutCharacter': '?',
        'shortcutModifiers': 0,
      }));
      final ShortcutSerialization serializationWithModifiers = ShortcutSerialization.character('?', alt: true, control: true, meta: true);
      expect(serializationWithModifiers.toChannelRepresentation(), equals(<String, Object?>{
        'shortcutCharacter': '?',
        'shortcutModifiers': 13,
      }));
    });

    testWidgets('modifier constructor', (WidgetTester tester) async {
      final ShortcutSerialization serialization = ShortcutSerialization.modifier(LogicalKeyboardKey.home);
      expect(serialization.toChannelRepresentation(), equals(<String, Object?>{
        'shortcutTrigger': LogicalKeyboardKey.home.keyId,
        'shortcutModifiers': 0,
      }));
      final ShortcutSerialization serializationWithModifiers = ShortcutSerialization.modifier(LogicalKeyboardKey.home, alt: true, control: true, meta: true, shift: true);
      expect(serializationWithModifiers.toChannelRepresentation(), equals(<String, Object?>{
        'shortcutTrigger': LogicalKeyboardKey.home.keyId,
        'shortcutModifiers': 15,
      }));
    });
  });
}

const List<String> mainMenu = <String>[
  'Menu 0',
  'Menu 1',
  'Menu 2',
  'Menu 3',
];

const List<String> subMenu0 = <String>[
  'Sub Menu 00',
];

const List<String> subMenu1 = <String>[
  'Sub Menu 10',
  'Sub Menu 11',
  'Sub Menu 12',
];

const List<String> subSubMenu10 = <String>[
  'Sub Sub Menu 110',
  'Sub Sub Menu 111',
  'Sub Sub Menu 112',
  'Sub Sub Menu 113',
];

const List<String> subMenu2 = <String>[
  'Sub Menu 20',
];

List<PlatformMenuItem> createTestMenus({
  void Function(String)? onActivate,
  void Function(String)? onOpen,
  void Function(String)? onClose,
  Map<String, MenuSerializableShortcut> shortcuts = const <String, MenuSerializableShortcut>{},
  bool includeStandard = false,
}) {
  final List<PlatformMenuItem> result = <PlatformMenuItem>[
    PlatformMenu(
      label: mainMenu[0],
      onOpen: onOpen != null ? () => onOpen(mainMenu[0]) : null,
      onClose: onClose != null ? () => onClose(mainMenu[0]) : null,
      menus: <PlatformMenuItem>[
        PlatformMenuItem(
          label: subMenu0[0],
          onSelected: onActivate != null ? () => onActivate(subMenu0[0]) : null,
          shortcut: shortcuts[subMenu0[0]],
        ),
      ],
    ),
    PlatformMenu(
      label: mainMenu[1],
      onOpen: onOpen != null ? () => onOpen(mainMenu[1]) : null,
      onClose: onClose != null ? () => onClose(mainMenu[1]) : null,
      menus: <PlatformMenuItem>[
        PlatformMenuItemGroup(
          members: <PlatformMenuItem>[
            PlatformMenuItem(
              label: subMenu1[0],
              onSelected: onActivate != null ? () => onActivate(subMenu1[0]) : null,
              shortcut: shortcuts[subMenu1[0]],
            ),
          ],
        ),
        PlatformMenu(
          label: subMenu1[1],
          onOpen: onOpen != null ? () => onOpen(subMenu1[1]) : null,
          onClose: onClose != null ? () => onClose(subMenu1[1]) : null,
          menus: <PlatformMenuItem>[
            PlatformMenuItemGroup(
              members: <PlatformMenuItem>[
                PlatformMenuItem(
                  label: subSubMenu10[0],
                  onSelected: onActivate != null ? () => onActivate(subSubMenu10[0]) : null,
                  shortcut: shortcuts[subSubMenu10[0]],
                ),
              ],
            ),
            PlatformMenuItemGroup(
              members: <PlatformMenuItem>[
                PlatformMenuItem(
                  label: subSubMenu10[1],
                  onSelected: onActivate != null ? () => onActivate(subSubMenu10[1]) : null,
                  shortcut: shortcuts[subSubMenu10[1]],
                ),
              ],
            ),
            PlatformMenuItem(
              label: subSubMenu10[2],
              onSelected: onActivate != null ? () => onActivate(subSubMenu10[2]) : null,
              shortcut: shortcuts[subSubMenu10[2]],
            ),
            PlatformMenuItemGroup(
              members: <PlatformMenuItem>[
                PlatformMenuItem(
                  label: subSubMenu10[3],
                  onSelected: onActivate != null ? () => onActivate(subSubMenu10[3]) : null,
                  shortcut: shortcuts[subSubMenu10[3]],
                ),
              ],
            ),
          ],
        ),
        PlatformMenuItem(
          label: subMenu1[2],
          onSelected: onActivate != null ? () => onActivate(subMenu1[2]) : null,
          shortcut: shortcuts[subMenu1[2]],
        ),
      ],
    ),
    PlatformMenu(
      label: mainMenu[2],
      onOpen: onOpen != null ? () => onOpen(mainMenu[2]) : null,
      onClose: onClose != null ? () => onClose(mainMenu[2]) : null,
      menus: <PlatformMenuItem>[
        PlatformMenuItem(
          // Always disabled.
          label: subMenu2[0],
          shortcut: shortcuts[subMenu2[0]],
        ),
      ],
    ),
    // Disabled menu
    PlatformMenu(
      label: mainMenu[3],
      onOpen: onOpen != null ? () => onOpen(mainMenu[2]) : null,
      onClose: onClose != null ? () => onClose(mainMenu[2]) : null,
      menus: <PlatformMenuItem>[],
    ),
  ];
  return result;
}

class FakeMenuChannel implements MethodChannel {
  FakeMenuChannel(this.outgoing);

  Future<dynamic> Function(MethodCall) outgoing;
  Future<void> Function(MethodCall)? incoming;

  List<MethodCall> outgoingCalls = <MethodCall>[];

  @override
  BinaryMessenger get binaryMessenger => throw UnimplementedError();

  @override
  MethodCodec get codec => const StandardMethodCodec();

  @override
  Future<List<T>> invokeListMethod<T>(String method, [dynamic arguments]) => throw UnimplementedError();

  @override
  Future<Map<K, V>> invokeMapMethod<K, V>(String method, [dynamic arguments]) => throw UnimplementedError();

  @override
  Future<T> invokeMethod<T>(String method, [dynamic arguments]) async {
    final MethodCall call = MethodCall(method, arguments);
    outgoingCalls.add(call);
    return await outgoing(call) as T;
  }

  @override
  String get name => 'flutter/menu';

  @override
  void setMethodCallHandler(Future<void> Function(MethodCall call)? handler) => incoming = handler;
}
