// 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"',
      ]);
    });
  });
}

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) : assert(outgoing != null);

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