// Copyright (c) 2011 The Chromium 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 "chrome/browser/ui/cocoa/nsmenuitem_additions.h"

#include <Carbon/Carbon.h>

#include <ostream>

#include "base/mac/scoped_nsobject.h"
#include "base/strings/sys_string_conversions.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/events/keycodes/keyboard_code_conversion_mac.h"

NSEvent* KeyEvent(const NSUInteger modifierFlags,
                  NSString* chars,
                  NSString* charsNoMods,
                  const NSUInteger keyCode) {
  return [NSEvent keyEventWithType:NSKeyDown
                          location:NSZeroPoint
                     modifierFlags:modifierFlags
                         timestamp:0.0
                      windowNumber:0
                           context:nil
                        characters:chars
       charactersIgnoringModifiers:charsNoMods
                         isARepeat:NO
                           keyCode:keyCode];
}

NSMenuItem* MenuItem(NSString* equiv, NSUInteger mask) {
  NSMenuItem* item = [[[NSMenuItem alloc] initWithTitle:@""
                                                 action:NULL
                                          keyEquivalent:@""] autorelease];
  [item setKeyEquivalent:equiv];
  [item setKeyEquivalentModifierMask:mask];
  return item;
}

std::ostream& operator<<(std::ostream& out, NSObject* obj) {
  return out << base::SysNSStringToUTF8([obj description]);
}

std::ostream& operator<<(std::ostream& out, NSMenuItem* item) {
  return out << "NSMenuItem " << base::SysNSStringToUTF8([item keyEquivalent]);
}

void ExpectKeyFiresItemEq(bool result, NSEvent* key, NSMenuItem* item,
    bool compareCocoa) {
  EXPECT_EQ(result, [item cr_firesForKeyEvent:key]) << key << '\n' << item;

  // Make sure that Cocoa does in fact agree with our expectations. However,
  // in some cases cocoa behaves weirdly (if you create e.g. a new event that
  // contains all fields of the event that you get when hitting cmd-a with a
  // russion keyboard layout, the copy won't fire a menu item that has cmd-a as
  // key equivalent, even though the original event would) and isn't a good
  // oracle function.
  if (compareCocoa) {
    base::scoped_nsobject<NSMenu> menu([[NSMenu alloc] initWithTitle:@"Menu!"]);
    [menu setAutoenablesItems:NO];
    EXPECT_FALSE([menu performKeyEquivalent:key]);
    [menu addItem:item];
    EXPECT_EQ(result, [menu performKeyEquivalent:key]) << key << '\n' << item;
  }
}

void ExpectKeyFiresItem(
    NSEvent* key, NSMenuItem* item, bool compareCocoa = true) {
  ExpectKeyFiresItemEq(true, key, item, compareCocoa);
}

void ExpectKeyDoesntFireItem(
    NSEvent* key, NSMenuItem* item, bool compareCocoa = true) {
  ExpectKeyFiresItemEq(false, key, item, compareCocoa);
}

TEST(NSMenuItemAdditionsTest, TestFiresForKeyEvent) {
  // These test cases were built by writing a small test app that has a
  // MainMenu.xib with a given key equivalent set in Interface Builder and a
  // some code that prints both the key equivalent that fires a menu item and
  // the menu item's key equivalent and modifier masks. I then pasted those
  // below. This was done with a US layout, unless otherwise noted. In the
  // comments, "z" always means the physical "z" key on a US layout no matter
  // what character that key produces.

  NSMenuItem* item;
  NSEvent* key;
  unichar ch;
  NSString* s;

  // Sanity
  item = MenuItem(@"", 0);
  EXPECT_TRUE([item isEnabled]);

  // a
  key = KeyEvent(0x100, @"a", @"a", 0);
  item = MenuItem(@"a", 0);
  ExpectKeyFiresItem(key, item);
  ExpectKeyDoesntFireItem(KeyEvent(0x20102, @"A", @"A", 0), item);

  // Disabled menu item
  key = KeyEvent(0x100, @"a", @"a", 0);
  item = MenuItem(@"a", 0);
  [item setEnabled:NO];
  ExpectKeyDoesntFireItem(key, item, false);

  // shift-a
  key = KeyEvent(0x20102, @"A", @"A", 0);
  item = MenuItem(@"A", 0);
  ExpectKeyFiresItem(key, item);
  ExpectKeyDoesntFireItem(KeyEvent(0x100, @"a", @"a", 0), item);

  // cmd-shift-t
  key = KeyEvent(0x12010a, @"t", @"T", 0);
  item = MenuItem(@"T", 0x100000);
  ExpectKeyFiresItem(key, item);
  item = MenuItem(@"t", 0x100000);
  ExpectKeyDoesntFireItem(key, item);

  // cmd-opt-shift-a
  key = KeyEvent(0x1a012a, @"\u00c5", @"A", 0);
  item = MenuItem(@"A", 0x180000);
  ExpectKeyFiresItem(key, item);

  // cmd-opt-a
  key = KeyEvent(0x18012a, @"\u00e5", @"a", 0);
  item = MenuItem(@"a", 0x180000);
  ExpectKeyFiresItem(key, item);

  // cmd-=
  key = KeyEvent(0x100110, @"=", @"=", 0x18);
  item = MenuItem(@"=", 0x100000);
  ExpectKeyFiresItem(key, item);

  // cmd-shift-=
  key = KeyEvent(0x12010a, @"=", @"+", 0x18);
  item = MenuItem(@"+", 0x100000);
  ExpectKeyFiresItem(key, item);

  // Turns out Cocoa fires "+ 100108 + 18" if you hit cmd-= and the menu only
  // has a cmd-+ shortcut. But that's transparent for |cr_firesForKeyEvent:|.

  // ctrl-3
  key = KeyEvent(0x40101, @"3", @"3", 0x14);
  item = MenuItem(@"3", 0x40000);
  ExpectKeyFiresItem(key, item);

  // return
  key = KeyEvent(0, @"\r", @"\r", 0x24);
  item = MenuItem(@"\r", 0);
  ExpectKeyFiresItem(key, item);

  // shift-return
  key = KeyEvent(0x20102, @"\r", @"\r", 0x24);
  item = MenuItem(@"\r", 0x20000);
  ExpectKeyFiresItem(key, item);

  // shift-left
  ch = NSLeftArrowFunctionKey;
  s = [NSString stringWithCharacters:&ch length:1];
  key = KeyEvent(0xa20102, s, s, 0x7b);
  item = MenuItem(s, 0x20000);
  ExpectKeyFiresItem(key, item);

  // shift-f1 (with a layout that needs the fn key down for f1)
  ch = NSF1FunctionKey;
  s = [NSString stringWithCharacters:&ch length:1];
  key = KeyEvent(0x820102, s, s, 0x7a);
  item = MenuItem(s, 0x20000);
  ExpectKeyFiresItem(key, item);

  // esc
  // Turns out this doesn't fire.
  key = KeyEvent(0x100, @"\e", @"\e", 0x35);
  item = MenuItem(@"\e", 0);
  ExpectKeyDoesntFireItem(key,item, false);

  // shift-esc
  // Turns out this doesn't fire.
  key = KeyEvent(0x20102, @"\e", @"\e", 0x35);
  item = MenuItem(@"\e", 0x20000);
  ExpectKeyDoesntFireItem(key,item, false);

  // cmd-esc
  key = KeyEvent(0x100108, @"\e", @"\e", 0x35);
  item = MenuItem(@"\e", 0x100000);
  ExpectKeyFiresItem(key, item);

  // ctrl-esc
  key = KeyEvent(0x40101, @"\e", @"\e", 0x35);
  item = MenuItem(@"\e", 0x40000);
  ExpectKeyFiresItem(key, item);

  // delete ("backspace")
  key = KeyEvent(0x100, @"\x7f", @"\x7f", 0x33);
  item = MenuItem(@"\x08", 0);
  ExpectKeyFiresItem(key, item, false);

  // shift-delete
  key = KeyEvent(0x20102, @"\x7f", @"\x7f", 0x33);
  item = MenuItem(@"\x08", 0x20000);
  ExpectKeyFiresItem(key, item, false);

  // forwarddelete (fn-delete / fn-backspace)
  ch = NSDeleteFunctionKey;
  s = [NSString stringWithCharacters:&ch length:1];
  key = KeyEvent(0x800100, s, s, 0x75);
  item = MenuItem(@"\x7f", 0);
  ExpectKeyFiresItem(key, item, false);

  // shift-forwarddelete (shift-fn-delete / shift-fn-backspace)
  ch = NSDeleteFunctionKey;
  s = [NSString stringWithCharacters:&ch length:1];
  key = KeyEvent(0x820102, s, s, 0x75);
  item = MenuItem(@"\x7f", 0x20000);
  ExpectKeyFiresItem(key, item, false);

  // fn-left
  ch = NSHomeFunctionKey;
  s = [NSString stringWithCharacters:&ch length:1];
  key = KeyEvent(0x800100, s, s, 0x73);
  item = MenuItem(s, 0);
  ExpectKeyFiresItem(key, item);

  // cmd-left
  ch = NSLeftArrowFunctionKey;
  s = [NSString stringWithCharacters:&ch length:1];
  key = KeyEvent(0xb00108, s, s, 0x7b);
  item = MenuItem(s, 0x100000);
  ExpectKeyFiresItem(key, item);

  // Hitting the "a" key with a russian keyboard layout -- does not fire
  // a menu item that has "a" as key equiv.
  key = KeyEvent(0x100, @"\u0444", @"\u0444", 0);
  item = MenuItem(@"a", 0);
  ExpectKeyDoesntFireItem(key,item);

  // cmd-a on a russion layout -- fires for a menu item with cmd-a as key equiv.
  key = KeyEvent(0x100108, @"a", @"\u0444", 0);
  item = MenuItem(@"a", 0x100000);
  ExpectKeyFiresItem(key, item, false);

  // cmd-z on US layout
  key = KeyEvent(0x100108, @"z", @"z", 6);
  item = MenuItem(@"z", 0x100000);
  ExpectKeyFiresItem(key, item);

  // cmd-y on german layout (has same keycode as cmd-z on us layout, shouldn't
  // fire).
  key = KeyEvent(0x100108, @"y", @"y", 6);
  item = MenuItem(@"z", 0x100000);
  ExpectKeyDoesntFireItem(key,item);

  // cmd-z on german layout
  key = KeyEvent(0x100108, @"z", @"z", 0x10);
  item = MenuItem(@"z", 0x100000);
  ExpectKeyFiresItem(key, item);

  // fn-return (== enter)
  key = KeyEvent(0x800100, @"\x3", @"\x3", 0x4c);
  item = MenuItem(@"\r", 0);
  ExpectKeyDoesntFireItem(key,item);

  // cmd-z on dvorak layout (so that the key produces ';')
  key = KeyEvent(0x100108, @";", @";", 6);
  ExpectKeyDoesntFireItem(key, MenuItem(@"z", 0x100000));
  ExpectKeyFiresItem(key, MenuItem(@";", 0x100000));

  // cmd-z on dvorak qwerty layout (so that the key produces ';', but 'z' if
  // cmd is down)
  SetIsInputSourceDvorakQwertyForTesting(true);
  key = KeyEvent(0x100108, @"z", @";", 6);
  ExpectKeyFiresItem(key, MenuItem(@"z", 0x100000), false);
  ExpectKeyDoesntFireItem(key, MenuItem(@";", 0x100000), false);
  SetIsInputSourceDvorakQwertyForTesting(false);

  // cmd-shift-z on dvorak layout (so that we get a ':')
  key = KeyEvent(0x12010a, @";", @":", 6);
  ExpectKeyFiresItem(key, MenuItem(@":", 0x100000));
  ExpectKeyDoesntFireItem(key, MenuItem(@";", 0x100000));

  // On PT layout, caps lock should not affect the keyEquivalent.
  key = KeyEvent(0x110108, @"T", @"t", 17);
  ExpectKeyFiresItem(key, MenuItem(@"t", 0x100000));
  ExpectKeyDoesntFireItem(key, MenuItem(@"T", 0x100000));

  // cmd-s with a serbian layout (just "s" produces something that looks a lot
  // like "c" in some fonts, but is actually \u0441. cmd-s activates a menu item
  // with key equivalent "s", not "c")
  key = KeyEvent(0x100108, @"s", @"\u0441", 1);
  ExpectKeyFiresItem(key, MenuItem(@"s", 0x100000), false);
  ExpectKeyDoesntFireItem(key, MenuItem(@"c", 0x100000));
}

NSString* keyCodeToCharacter(NSUInteger keyCode,
                             EventModifiers modifiers,
                             TISInputSourceRef layout) {
  UInt32 deadKeyStateUnused = 0;
  UniChar unicodeChar = ui::TranslatedUnicodeCharFromKeyCode(
      layout, (UInt16)keyCode, kUCKeyActionDown, modifiers, LMGetKbdType(),
      &deadKeyStateUnused);

  CFStringRef temp =
      CFStringCreateWithCharacters(kCFAllocatorDefault, &unicodeChar, 1);
  return [(NSString*)temp autorelease];
}

TEST(NSMenuItemAdditionsTest, TestMOnDifferentLayouts) {
  // There's one key -- "m" -- that has the same keycode on most keyboard
  // layouts. This function tests a menu item with cmd-m as key equivalent
  // can be fired on all layouts.
  NSMenuItem* item = MenuItem(@"m", 0x100000);

  NSDictionary* filter = [NSDictionary
    dictionaryWithObject:(NSString*)kTISTypeKeyboardLayout
                  forKey:(NSString*)kTISPropertyInputSourceType];

  // Docs say that including all layouts instead of just the active ones is
  // slow, but there's no way around that.
  NSArray* list = (NSArray*)TISCreateInputSourceList(
      (CFDictionaryRef)filter, true);
  for (id layout in list) {
    TISInputSourceRef ref = (TISInputSourceRef)layout;

    NSUInteger keyCode = 0x2e;  // "m" on a US layout and most other layouts.

    // On a few layouts, "m" has a different key code.
    NSString* layoutId = (NSString*)TISGetInputSourceProperty(
        ref, kTISPropertyInputSourceID);
    if ([layoutId isEqualToString:@"com.apple.keylayout.Belgian"] ||
        [layoutId isEqualToString:@"com.apple.keylayout.Italian"] ||
        [layoutId isEqualToString:@"com.apple.keylayout.ABC-AZERTY"] ||
        [layoutId hasPrefix:@"com.apple.keylayout.French"]) {
      keyCode = 0x29;
    } else if ([layoutId isEqualToString:@"com.apple.keylayout.Turkish"] ||
               [layoutId
                   isEqualToString:@"com.apple.keylayout.Turkish-Standard"]) {
      keyCode = 0x28;
    } else if ([layoutId isEqualToString:@"com.apple.keylayout.Dvorak-Left"]) {
      keyCode = 0x16;
    } else if ([layoutId isEqualToString:@"com.apple.keylayout.Dvorak-Right"]) {
      keyCode = 0x1a;
    } else if ([layoutId
                   isEqualToString:@"com.apple.keylayout.Tibetan-Wylie"]) {
      // In Tibetan-Wylie, the only way to type the "m" character is with cmd +
      // key_code=0x2e. As such, it doesn't make sense for this same combination
      // to trigger a keyEquivalent, since then it won't be possible to type
      // "m".
      continue;
    }

    if ([layoutId isEqualToString:@"com.apple.keylayout.DVORAK-QWERTYCMD"]) {
      SetIsInputSourceDvorakQwertyForTesting(true);
    }

    EventModifiers modifiers = cmdKey >> 8;
    NSString* chars = keyCodeToCharacter(keyCode, modifiers, ref);
    NSString* charsIgnoringMods = keyCodeToCharacter(keyCode, 0, ref);
    NSEvent* key = KeyEvent(0x100000, chars, charsIgnoringMods, keyCode);
    ExpectKeyFiresItem(key, item, false);

    if ([layoutId isEqualToString:@"com.apple.keylayout.DVORAK-QWERTYCMD"]) {
      SetIsInputSourceDvorakQwertyForTesting(false);
    }
  }
  CFRelease(list);
}
