// Copyright 2010-2015, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#import "mac/KeyCodeMap.h"

#import <Carbon/Carbon.h>
#import <Cocoa/Cocoa.h>

#include "session/commands.pb.h"
#include "testing/base/public/googletest.h"
#include "testing/base/public/gunit.h"

using mozc::commands::KeyEvent;

struct TestCase {
  string title;
  NSString *characters;
  NSString *unmodCharacters;
  int flags;
  uint16 keyCode;
  string expected;
};

class KeyCodeMapTest : public testing::Test {
 protected:
  void SetUp() {
    pool_  = [[NSAutoreleasePool alloc] init];
    keyCodeMap_ = [[[KeyCodeMap alloc] init] autorelease];
  }

  void TearDown() {
    [pool_ drain];
  }

  void KanaMode() {
    keyCodeMap_.inputMode = KANA;
  }

  bool CreateKeyEvent(NSString *characters, NSString *unmodCharacters,
                      int flags, uint16 keyCode, KeyEvent *mozcKeyEvent) {
    if (mozcKeyEvent == NULL) {
      return false;
    }

    NSEventType type = NSKeyDown;
    // if the key event is just pressing modifiers, the type should be
    // NSFlagsChanged.
    if (characters == nil && unmodCharacters == nil) {
      type = NSFlagsChanged;
    }

    if (characters == nil) {
      characters = @"";
    }
    if (unmodCharacters == nil) {
      unmodCharacters = [[characters copy] autorelease];
    }

    NSEvent *event = [NSEvent keyEventWithType:type
                                      location:NSZeroPoint
                                 modifierFlags:flags
                                     timestamp:0.0
                                  windowNumber:0
                                       context:nil
                                    characters:characters
                   charactersIgnoringModifiers:unmodCharacters
                                     isARepeat:NO
                                       keyCode:keyCode];
    return [keyCodeMap_ getMozcKeyCodeFromKeyEvent:event
                                    toMozcKeyEvent:mozcKeyEvent];
  }

  bool CreateKeyEventFromTestCase(const TestCase &testCase,
                                  KeyEvent *mozcKeyEvent) {
    return CreateKeyEvent(testCase.characters, testCase.unmodCharacters,
                          testCase.flags, testCase.keyCode, mozcKeyEvent);
  }

 private:
  NSAutoreleasePool *pool_;
  KeyCodeMap *keyCodeMap_;
};

static const TestCase kKeyEventTestCases[] = {
  { "normal a", @"a", nil, 0, kVK_ANSI_A, "key_code: 97\n" },
  { "\\S-a", @"A", @"a", NSShiftKeyMask, kVK_ANSI_A, "key_code: 65\n" },
  { "\\C-a", @"\x01", @"a", NSControlKeyMask, kVK_ANSI_A,
    "key_code: 97\n"
    "modifier_keys: CTRL\n"
  },
  { "\\S-C-a", @"a", nil, NSControlKeyMask | NSShiftKeyMask, kVK_ANSI_A,
    "key_code: 97\n"
    "modifier_keys: SHIFT\n"
    "modifier_keys: CTRL\n"
  },
  { "Tab key", @"\x09", nil, 0, kVK_Tab, "special_key: TAB\n" },
  { "\\S-Tab", @"\x09", nil, NSShiftKeyMask, kVK_Tab,
    "special_key: TAB\n"
    "modifier_keys: SHIFT\n"
  },
  { "function key", @"\x10", nil, 0, kVK_F1, "special_key: F1\n" },
  { "tenkey", @"0", nil, 0, kVK_ANSI_Keypad0, "special_key: NUMPAD0\n" }
};

static const TestCase kKanaTypingTestCases[] = {
  { "a -> ち", @"a", nil, 0, kVK_ANSI_A,
    "key_code: 97\n"
    "key_string: \"\\343\\201\\241\"\n"
  },
  { "yen mark", @"¥", nil, 0, kVK_JIS_Yen,
    "key_code: 92\n"
    "key_string: \"\\343\\203\\274\"\n"
  },
  { "\\S-2 -> ふ", @"@", @"2", NSShiftKeyMask, kVK_ANSI_2,
    "key_code: 64\n"
    "key_string: \"\\343\\201\\265\"\n"
  },
  { "\\C-a -> \\C-a", @"\x01", @"a", NSControlKeyMask, kVK_ANSI_A,
    "key_code: 97\n"
    "modifier_keys: CTRL\n"
    "key_string: \"\\343\\201\\241\"\n"
  },
  { "\\S-0 -> を", @"0", nil, NSShiftKeyMask, kVK_ANSI_0,
    "key_code: 48\n"
    "key_string: \"\\343\\202\\222\"\n"
  },
  { "yen mark -> ー", @"￥", nil, 0, kVK_JIS_Yen,
    "key_string: \"\\343\\203\\274\"\n"
  },
  { "underscore -> ろ", @"_", nil, 0, kVK_JIS_Underscore,
    "key_code: 95\n"
    "key_string: \"\\343\\202\\215\"\n"
  },
  { "@ -> ゛ in JIS keyboard", @"@", nil, 0, kVK_ANSI_LeftBracket,
    "key_code: 64\n"
    "key_string: \"\\343\\202\\233\"\n"
  },
  { "[ -> ゛ in US keyboard", @"[", nil, 0, kVK_ANSI_LeftBracket,
    "key_code: 91\n"
    "key_string: \"\\343\\202\\233\"\n"
  },
};

// Test for romaji typing
TEST_F(KeyCodeMapTest, NormaKeyEvent) {
  KeyEvent event;
  for (int i = 0; i < arraysize(kKeyEventTestCases); ++i) {
    const TestCase &testCase = kKeyEventTestCases[i];
    event.Clear();
    EXPECT_TRUE(CreateKeyEventFromTestCase(testCase, &event));
    EXPECT_EQ(testCase.expected, event.DebugString()) << testCase.title;
  }
}

// Test for kana typing
TEST_F(KeyCodeMapTest, KanaEvent) {
  KanaMode();
  KeyEvent event;
  for (int i = 0; i < arraysize(kKanaTypingTestCases); ++i) {
    const TestCase &testCase = kKanaTypingTestCases[i];
    event.Clear();
    EXPECT_TRUE(CreateKeyEventFromTestCase(testCase, &event));
    EXPECT_EQ(testCase.expected, event.DebugString()) << testCase.title;
  }
}

// Test for modifier key events
TEST_F(KeyCodeMapTest, Modifiers) {
  KeyEvent event;
  TestCase testCase;
  // Press shift key
  EXPECT_FALSE(CreateKeyEvent(nil, nil, NSShiftKeyMask, kVK_Shift, &event));

  // Release the shift key -> emit Shift-key event
  event.Clear();
  EXPECT_TRUE(CreateKeyEvent(nil, nil, 0, kVK_Shift, &event));
  EXPECT_EQ("modifier_keys: SHIFT\n", event.DebugString());

  // Press shift key
  event.Clear();
  EXPECT_FALSE(CreateKeyEvent(nil, nil, NSShiftKeyMask, kVK_Shift, &event));

  // Press control key
  event.Clear();
  EXPECT_FALSE(CreateKeyEvent(
      nil, nil, NSShiftKeyMask | NSControlKeyMask, kVK_Control, &event));

  // Release shift key
  event.Clear();
  EXPECT_FALSE(CreateKeyEvent(nil, nil, NSControlKeyMask, kVK_Control, &event));

  // Release control key -> emit Control + Shift
  event.Clear();
  EXPECT_TRUE(CreateKeyEvent(nil, nil, 0, kVK_Control, &event));
  EXPECT_EQ("modifier_keys: SHIFT\nmodifier_keys: CTRL\n", event.DebugString());

  // Press control key
  event.Clear();
  EXPECT_FALSE(CreateKeyEvent(nil, nil, NSControlKeyMask, kVK_Control, &event));

  // Press a -> emit \C-a
  event.Clear();
  EXPECT_TRUE(CreateKeyEvent(@"a", nil, NSControlKeyMask, kVK_ANSI_A, &event));
  EXPECT_EQ("key_code: 97\nmodifier_keys: CTRL\n", event.DebugString());

  // Release control key -> Doesn't emit any key events
  event.Clear();
  EXPECT_FALSE(CreateKeyEvent(nil, nil, 0, kVK_Control, &event));
}
