// 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.

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

#include <algorithm>
#include <functional>

#include "base/bind.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/spellchecker/spellcheck_factory.h"
#include "chrome/browser/spellchecker/spellcheck_platform_mac.h"
#include "chrome/browser/spellchecker/spellcheck_service.h"
#include "chrome/browser/spellchecker/spelling_service_client.h"
#include "chrome/common/spellcheck_messages.h"
#include "chrome/common/spellcheck_result.h"
#include "content/public/browser/render_process_host.h"

using content::BrowserThread;

namespace {

bool CompareLocation(const SpellCheckResult& r1,
                     const SpellCheckResult& r2) {
  return r1.location < r2.location;
}

}  // namespace

class SpellingRequest {
 public:
  SpellingRequest(SpellingServiceClient* client,
                  content::BrowserMessageFilter* destination,
                  int render_process_id);

  void RequestCheck(const string16& text,
                    int route_id,
                    int identifier,
                    int document_tag,
                    const std::vector<SpellCheckMarker>& markers);
 private:
  // Request server-side checking.
  void RequestRemoteCheck(const string16& text);

  // Request a check from local spell checker.
  void RequestLocalCheck(const string16& text, int document_tag);

  // Check if all pending requests are done, send reply to render process if so.
  void OnCheckCompleted();

  // Called when server-side checking is complete.
  void OnRemoteCheckCompleted(bool success,
                              const string16& text,
                              const std::vector<SpellCheckResult>& results);

  // Called when local checking is complete.
  void OnLocalCheckCompleted(const std::vector<SpellCheckResult>& results);

  std::vector<SpellCheckResult> local_results_;
  std::vector<SpellCheckResult> remote_results_;

  bool local_pending_;
  bool remote_pending_;
  bool remote_success_;

  SpellingServiceClient* client_;  // Owned by |destination|.
  content::BrowserMessageFilter* destination_;  // ref-counted.
  int render_process_id_;

  int route_id_;
  int identifier_;
  int document_tag_;
  std::vector<SpellCheckMarker> markers_;
};

SpellingRequest::SpellingRequest(SpellingServiceClient* client,
                                 content::BrowserMessageFilter* destination,
                                 int render_process_id)
    : local_pending_(true),
      remote_pending_(true),
      client_(client),
      destination_(destination),
      render_process_id_(render_process_id),
      route_id_(-1),
      identifier_(-1),
      document_tag_(-1) {
  destination_->AddRef();
}

void SpellingRequest::RequestCheck(
    const string16& text,
    int route_id,
    int identifier,
    int document_tag,
    const std::vector<SpellCheckMarker>& markers) {
  DCHECK(!text.empty());
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));

  route_id_ = route_id;
  identifier_ = identifier;
  document_tag_ = document_tag;
  markers_ = markers;

  // Send the remote query out.
  RequestRemoteCheck(text);
  RequestLocalCheck(text, document_tag_);
}

void SpellingRequest::RequestRemoteCheck(const string16& text) {
  Profile* profile = NULL;
  content::RenderProcessHost* host =
      content::RenderProcessHost::FromID(render_process_id_);
  if (host)
    profile = Profile::FromBrowserContext(host->GetBrowserContext());

  client_->RequestTextCheck(
    profile,
    SpellingServiceClient::SPELLCHECK,
    text,
    base::Bind(&SpellingRequest::OnRemoteCheckCompleted,
               base::Unretained(this)));
}

void SpellingRequest::RequestLocalCheck(const string16& text,
                                        int document_tag) {
  spellcheck_mac::RequestTextCheck(
      document_tag,
      text,
      base::Bind(&SpellingRequest::OnLocalCheckCompleted,
                 base::Unretained(this)));
}

void SpellingRequest::OnCheckCompleted() {
  // Final completion can happen on any thread - don't DCHECK thread.

  if (local_pending_ || remote_pending_)
    return;

  const std::vector<SpellCheckResult>* check_results = &local_results_;
  if (remote_success_) {
    std::sort(remote_results_.begin(), remote_results_.end(), CompareLocation);
    std::sort(local_results_.begin(), local_results_.end(), CompareLocation);
    SpellCheckMessageFilterMac::CombineResults(&remote_results_,
                                               local_results_);
    check_results = &remote_results_;
  }

  destination_->Send(
      new SpellCheckMsg_RespondTextCheck(
          route_id_,
          identifier_,
          *check_results));
  destination_->Release();

  // Object is self-managed - at this point, its life span is over.
  delete this;
}

void SpellingRequest::OnRemoteCheckCompleted(
    bool success,
    const string16& text,
    const std::vector<SpellCheckResult>& results) {
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  remote_success_ = success;
  remote_results_ = results;
  remote_pending_ = false;

  SpellcheckService* spellcheck_service =
      SpellcheckServiceFactory::GetForRenderProcessId(render_process_id_);
  if (spellcheck_service) {
    spellcheck_service->GetFeedbackSender()->OnSpellcheckResults(
        render_process_id_,
        text,
        markers_,
        &remote_results_);
  }

  OnCheckCompleted();
}

void SpellingRequest::OnLocalCheckCompleted(
    const std::vector<SpellCheckResult>& results) {
  // Local checking can happen on any thread - don't DCHECK thread.

  local_results_ = results;
  local_pending_ = false;

  OnCheckCompleted();
}


SpellCheckMessageFilterMac::SpellCheckMessageFilterMac(int render_process_id)
    : render_process_id_(render_process_id),
      client_(new SpellingServiceClient) {
}

void SpellCheckMessageFilterMac::OverrideThreadForMessage(
    const IPC::Message& message, BrowserThread::ID* thread) {
  if (message.type() == SpellCheckHostMsg_RequestTextCheck::ID)
    *thread = BrowserThread::UI;
}

bool SpellCheckMessageFilterMac::OnMessageReceived(const IPC::Message& message,
                                                   bool* message_was_ok) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP_EX(SpellCheckMessageFilterMac, message, *message_was_ok)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_CheckSpelling,
                        OnCheckSpelling)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_FillSuggestionList,
                        OnFillSuggestionList)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_ShowSpellingPanel,
                        OnShowSpellingPanel)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_UpdateSpellingPanelWithMisspelledWord,
                        OnUpdateSpellingPanelWithMisspelledWord)
    IPC_MESSAGE_HANDLER(SpellCheckHostMsg_RequestTextCheck,
                        OnRequestTextCheck)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

// static
void SpellCheckMessageFilterMac::CombineResults(
    std::vector<SpellCheckResult>* remote_results,
    const std::vector<SpellCheckResult>& local_results) {
  std::vector<SpellCheckResult>::const_iterator local_iter(
      local_results.begin());
  std::vector<SpellCheckResult>::iterator remote_iter;

  for (remote_iter = remote_results->begin();
       remote_iter != remote_results->end();
       ++remote_iter) {
    // Discard all local results occurring before remote result.
    while (local_iter != local_results.end() &&
           local_iter->location < remote_iter->location) {
      local_iter++;
    }

    // Unless local and remote result coincide, result is GRAMMAR.
    remote_iter->type = SpellCheckResult::GRAMMAR;
    if (local_iter != local_results.end() &&
        local_iter->location == remote_iter->location &&
        local_iter->length == remote_iter->length) {
      remote_iter->type = SpellCheckResult::SPELLING;
    }
  }
}

SpellCheckMessageFilterMac::~SpellCheckMessageFilterMac() {}

void SpellCheckMessageFilterMac::OnCheckSpelling(const string16& word,
                                                 int route_id,
                                                 bool* correct) {
  *correct = spellcheck_mac::CheckSpelling(word, ToDocumentTag(route_id));
}

void SpellCheckMessageFilterMac::OnFillSuggestionList(
    const string16& word,
    std::vector<string16>* suggestions) {
  spellcheck_mac::FillSuggestionList(word, suggestions);
}

void SpellCheckMessageFilterMac::OnShowSpellingPanel(bool show) {
  spellcheck_mac::ShowSpellingPanel(show);
}

void SpellCheckMessageFilterMac::OnUpdateSpellingPanelWithMisspelledWord(
    const string16& word) {
  spellcheck_mac::UpdateSpellingPanelWithMisspelledWord(word);
}

void SpellCheckMessageFilterMac::OnRequestTextCheck(
    int route_id,
    int identifier,
    const string16& text,
    std::vector<SpellCheckMarker> markers) {
  DCHECK(!text.empty());
  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
  // Erase invalid markers (with offsets out of boundaries of text length).
  markers.erase(
      std::remove_if(
          markers.begin(),
          markers.end(),
          std::not1(SpellCheckMarker::IsValidPredicate(text.length()))),
      markers.end());
  // SpellingRequest self-destructs.
  SpellingRequest* request =
    new SpellingRequest(client_.get(), this, render_process_id_);
  request->RequestCheck(
      text, route_id, identifier, ToDocumentTag(route_id), markers);
}

int SpellCheckMessageFilterMac::ToDocumentTag(int route_id) {
  if (!tag_map_.count(route_id))
    tag_map_[route_id] = spellcheck_mac::GetDocumentTag();
  return tag_map_[route_id];
}

// TODO(groby): We are currently not notified of retired tags. We need
// to track destruction of RenderViewHosts on the browser process side
// to update our mappings when a document goes away.
void SpellCheckMessageFilterMac::RetireDocumentTag(int route_id) {
  spellcheck_mac::CloseDocumentWithTag(ToDocumentTag(route_id));
  tag_map_.erase(route_id);
}

