// Copyright (c) 2012 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.

// Integration with OS X native spellchecker.

#include "chrome/browser/spellchecker/spellcheck_platform_mac.h"

#import <Cocoa/Cocoa.h>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/mac/foundation_util.h"
#include "base/mac/scoped_nsexception_enabler.h"
#include "base/metrics/histogram.h"
#include "base/strings/sys_string_conversions.h"
#include "base/time/time.h"
#include "chrome/common/spellcheck_common.h"
#include "chrome/common/spellcheck_messages.h"
#include "chrome/common/spellcheck_result.h"
#include "content/public/browser/browser_message_filter.h"
#include "content/public/browser/browser_thread.h"

using base::TimeTicks;
using content::BrowserMessageFilter;
using content::BrowserThread;

namespace {
// The number of characters in the first part of the language code.
const unsigned int kShortLanguageCodeSize = 2;

// +[NSSpellChecker sharedSpellChecker] can throw exceptions depending
// on the state of the pasteboard, or possibly as a result of
// third-party code (when setting up services entries).  The following
// receives nil if an exception is thrown, in which case
// spell-checking will not work, but it also will not crash the
// browser.
NSSpellChecker* SharedSpellChecker() {
  return base::mac::ObjCCastStrict<NSSpellChecker>(
      base::mac::RunBlockIgnoringExceptions(^{
          return [NSSpellChecker sharedSpellChecker];
      }));
}

// A private utility function to convert hunspell language codes to OS X
// language codes.
NSString* ConvertLanguageCodeToMac(const std::string& hunspell_lang_code) {
  NSString* whole_code = base::SysUTF8ToNSString(hunspell_lang_code);

  if ([whole_code length] > kShortLanguageCodeSize) {
    NSString* lang_code = [whole_code
                           substringToIndex:kShortLanguageCodeSize];
    // Add 1 here to skip the underscore.
    NSString* region_code = [whole_code
                             substringFromIndex:(kShortLanguageCodeSize + 1)];

    // Check for the special case of en-US and pt-PT, since OS X lists these
    // as just en and pt respectively.
    // TODO(pwicks): Find out if there are other special cases for languages
    // not installed on the system by default. Are there others like pt-PT?
    if (([lang_code isEqualToString:@"en"] &&
       [region_code isEqualToString:@"US"]) ||
        ([lang_code isEqualToString:@"pt"] &&
       [region_code isEqualToString:@"PT"])) {
      return lang_code;
    }

    // Otherwise, just build a string that uses an underscore instead of a
    // dash between the language and the region code, since this is the
    // format that OS X uses.
    NSString* os_x_language =
        [NSString stringWithFormat:@"%@_%@", lang_code, region_code];
    return os_x_language;
  } else {
    // Special case for Polish.
    if ([whole_code isEqualToString:@"pl"]) {
      return @"pl_PL";
    }
    // This is just a language code with the same format as OS X
    // language code.
    return whole_code;
  }
}

std::string ConvertLanguageCodeFromMac(NSString* lang_code) {
  // TODO(pwicks):figure out what to do about Multilingual
  // Guards for strange cases.
  if ([lang_code isEqualToString:@"en"]) return std::string("en-US");
  if ([lang_code isEqualToString:@"pt"]) return std::string("pt-PT");
  if ([lang_code isEqualToString:@"pl_PL"]) return std::string("pl");

  if ([lang_code length] > kShortLanguageCodeSize &&
      [lang_code characterAtIndex:kShortLanguageCodeSize] == '_') {
    return base::SysNSStringToUTF8([NSString stringWithFormat:@"%@-%@",
                [lang_code substringToIndex:kShortLanguageCodeSize],
                [lang_code substringFromIndex:(kShortLanguageCodeSize + 1)]]);
  }
  return base::SysNSStringToUTF8(lang_code);
}

} // namespace

namespace spellcheck_mac {

void GetAvailableLanguages(std::vector<std::string>* spellcheck_languages) {
  NSArray* availableLanguages = [SharedSpellChecker() availableLanguages];
  for (NSString* lang_code in availableLanguages) {
    spellcheck_languages->push_back(
              ConvertLanguageCodeFromMac(lang_code));
  }
}

bool SpellCheckerAvailable() {
  // If this file was compiled, then we know that we are on OS X 10.5 at least
  // and can safely return true here.
  return true;
}

bool SpellCheckerProvidesPanel() {
  // OS X has a Spelling Panel, so we can return true here.
  return true;
}

bool SpellingPanelVisible() {
  // This should only be called from the main thread.
  DCHECK([NSThread currentThread] == [NSThread mainThread]);
  return [[SharedSpellChecker() spellingPanel] isVisible];
}

void ShowSpellingPanel(bool show) {
  if (show) {
    [[SharedSpellChecker() spellingPanel]
        performSelectorOnMainThread:@selector(makeKeyAndOrderFront:)
                         withObject:nil
                      waitUntilDone:YES];
  } else {
    [[SharedSpellChecker() spellingPanel]
        performSelectorOnMainThread:@selector(close)
                         withObject:nil
                      waitUntilDone:YES];
  }
}

void UpdateSpellingPanelWithMisspelledWord(const base::string16& word) {
  NSString * word_to_display = base::SysUTF16ToNSString(word);
  [SharedSpellChecker()
      performSelectorOnMainThread:
        @selector(updateSpellingPanelWithMisspelledWord:)
                       withObject:word_to_display
                    waitUntilDone:YES];
}

bool PlatformSupportsLanguage(const std::string& current_language) {
  // First, convert the language to an OS X language code.
  NSString* mac_lang_code = ConvertLanguageCodeToMac(current_language);

  // Then grab the languages available.
  NSArray* availableLanguages = [SharedSpellChecker() availableLanguages];

  // Return true if the given language is supported by OS X.
  return [availableLanguages containsObject:mac_lang_code];
}

void SetLanguage(const std::string& lang_to_set) {
  // Do not set any language right now, since Chrome should honor the
  // system spellcheck settings. (http://crbug.com/166046)
  // Fix this once Chrome actually allows setting a spellcheck language
  // in chrome://settings.
  //  NSString* NS_lang_to_set = ConvertLanguageCodeToMac(lang_to_set);
  //  [SharedSpellChecker() setLanguage:NS_lang_to_set];
}

static int last_seen_tag_;

bool CheckSpelling(const base::string16& word_to_check, int tag) {
  last_seen_tag_ = tag;

  // -[NSSpellChecker checkSpellingOfString] returns an NSRange that
  // we can look at to determine if a word is misspelled.
  NSRange spell_range = {0,0};

  // Convert the word to an NSString.
  NSString* NS_word_to_check = base::SysUTF16ToNSString(word_to_check);
  // Check the spelling, starting at the beginning of the word.
  spell_range = [SharedSpellChecker()
                  checkSpellingOfString:NS_word_to_check startingAt:0
                  language:nil wrap:NO inSpellDocumentWithTag:tag
                  wordCount:NULL];

  // If the length of the misspelled word == 0,
  // then there is no misspelled word.
  bool word_correct = (spell_range.length == 0);
  return word_correct;
}

void FillSuggestionList(const base::string16& wrong_word,
                        std::vector<base::string16>* optional_suggestions) {
  NSString* NS_wrong_word = base::SysUTF16ToNSString(wrong_word);
  TimeTicks debug_begin_time = base::Histogram::DebugNow();
  // The suggested words for |wrong_word|.
  NSArray* guesses = [SharedSpellChecker() guessesForWord:NS_wrong_word];
  DHISTOGRAM_TIMES("Spellcheck.SuggestTime",
                   base::Histogram::DebugNow() - debug_begin_time);

  for (int i = 0; i < static_cast<int>([guesses count]); ++i) {
    if (i < chrome::spellcheck_common::kMaxSuggestions) {
      optional_suggestions->push_back(base::SysNSStringToUTF16(
                                      [guesses objectAtIndex:i]));
    }
  }
}

void AddWord(const base::string16& word) {
    NSString* word_to_add = base::SysUTF16ToNSString(word);
  [SharedSpellChecker() learnWord:word_to_add];
}

void RemoveWord(const base::string16& word) {
  NSString *word_to_remove = base::SysUTF16ToNSString(word);
  [SharedSpellChecker() unlearnWord:word_to_remove];
}

int GetDocumentTag() {
  NSInteger doc_tag = [NSSpellChecker uniqueSpellDocumentTag];
  return static_cast<int>(doc_tag);
}

void IgnoreWord(const base::string16& word) {
  [SharedSpellChecker() ignoreWord:base::SysUTF16ToNSString(word)
            inSpellDocumentWithTag:last_seen_tag_];
}

void CloseDocumentWithTag(int tag) {
  [SharedSpellChecker() closeSpellDocumentWithTag:static_cast<NSInteger>(tag)];
}

void RequestTextCheck(int document_tag,
                      const base::string16& text,
                      TextCheckCompleteCallback callback) {
  NSString* text_to_check = base::SysUTF16ToNSString(text);
  NSRange range_to_check = NSMakeRange(0, [text_to_check length]);

  [SharedSpellChecker()
      requestCheckingOfString:text_to_check
                        range:range_to_check
                        types:NSTextCheckingTypeSpelling
                      options:nil
       inSpellDocumentWithTag:document_tag
            completionHandler:^(NSInteger,
                                NSArray *results,
                                NSOrthography*,
                                NSInteger) {
          std::vector<SpellCheckResult> check_results;
          for (NSTextCheckingResult* result in results) {
            // Deliberately ignore non-spelling results. OSX at the very least
            // delivers a result of NSTextCheckingTypeOrthography for the
            // whole fragment, which underlines the entire checked range.
            if ([result resultType] != NSTextCheckingTypeSpelling)
              continue;

            // In this use case, the spell checker should never
            // return anything but a single range per result.
            check_results.push_back(SpellCheckResult(
                SpellCheckResult::SPELLING,
                [result range].location,
                [result range].length));
          }
          // TODO(groby): Verify we don't need to post from here.
          callback.Run(check_results);
      }];
}

class SpellcheckerStateInternal {
 public:
  SpellcheckerStateInternal();
  ~SpellcheckerStateInternal();

 private:
  BOOL automaticallyIdentifiesLanguages_;
  NSString* language_;
};

SpellcheckerStateInternal::SpellcheckerStateInternal() {
  language_ = [SharedSpellChecker() language];
  automaticallyIdentifiesLanguages_ =
      [SharedSpellChecker() automaticallyIdentifiesLanguages];
  [SharedSpellChecker() setLanguage:@"en"];
  [SharedSpellChecker() setAutomaticallyIdentifiesLanguages:NO];
}

SpellcheckerStateInternal::~SpellcheckerStateInternal() {
  [SharedSpellChecker() setLanguage:language_];
  [SharedSpellChecker() setAutomaticallyIdentifiesLanguages:
      automaticallyIdentifiesLanguages_];
}

ScopedEnglishLanguageForTest::ScopedEnglishLanguageForTest()
    : state_(new SpellcheckerStateInternal) {
}

ScopedEnglishLanguageForTest::~ScopedEnglishLanguageForTest() {
  delete state_;
}

}  // namespace spellcheck_mac
