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

#include "win32/ime/ime_candidate_info.h"

#include <safeint.h>
#include <windows.h>  // windows.h must be included before strsafe.h
#include <strsafe.h>

#include <algorithm>

#include "google/protobuf/stubs/common.h"
#include "base/logging.h"
#include "base/util.h"
#include "session/commands.pb.h"
#include "win32/ime/ime_ui_window.h"

namespace mozc {
namespace win32 {
namespace {

using ::mozc::commands::CandidateList;
using ::mozc::commands::Candidates;

using ::msl::utilities::SafeAdd;
using ::msl::utilities::SafeCast;
using ::msl::utilities::SafeMultiply;
using ::msl::utilities::SafeSubtract;

// Since IMM32 uses DWORD rather than size_t for data size in data structures,
// relevant data size are stored into DWORD constants here.
static_assert(sizeof(DWORD) <= kint32max, "Check DWORD size.");

const DWORD kSizeOfDWORD = static_cast<DWORD>(sizeof(DWORD));

static_assert(sizeof(wchar_t) <= kint32max, "Check wchar_t size.");
const DWORD kSizeOfWCHAR = static_cast<DWORD>(sizeof(wchar_t));

static_assert(sizeof(CANDIDATEINFO) <= kint32max, "Check CANDIDATEINFO size.");
const DWORD kSizeOfCANDIDATEINFO = static_cast<DWORD>(sizeof(CANDIDATEINFO));

static_assert(sizeof(CANDIDATELIST) <= kint32max, "Check CANDIDATELIST size.");
const DWORD kSizeOfCANDIDATELIST = static_cast<DWORD>(sizeof(CANDIDATELIST));

static_assert(sizeof(CANDIDATELIST) > sizeof(DWORD),
              "Check CANDIDATELIST size.");
const DWORD kSizeOfCANDIDATELISTHeader =
    static_cast<DWORD>(sizeof(CANDIDATELIST) - sizeof(DWORD));

static_assert((static_cast<int64>(sizeof(CANDIDATEINFO)) +
               static_cast<int64>(sizeof(CANDIDATELIST))) < kint32max,
               "Check CANDIDATEINFO + CANDIDATELIST size.");
const DWORD kSizeOfCANDIDATEINFOAndCANDIDATELIST =
    static_cast<DWORD>(sizeof(CANDIDATEINFO) + sizeof(CANDIDATELIST));

// Some games such as EMIL CHRONICLE ONLINE assumes that
// CANDIDATELIST::dwPageSize never be zero nor greater than 10 despite that
// the WDK document for IMM32 declares this field can be 0.  See b/3033499.
// We conform to those applications by always setting a safe number.
// Note that Office-IME 2010 always returns 9 CANDIDATELIST::dwPageSize
// regardless of the actual number of candidates.  So we use the same strategy.
const int kSafePageSize = 9;

bool GetCandidateCountInternal(
    const CANDIDATEINFO *info, DWORD buffer_size, DWORD *count) {
  DCHECK_NE(nullptr, info);
  DCHECK_NE(nullptr, count);

  if (info->dwCount < 1) {
    return false;
  }

  // |count_data_offset = info->dwOffset[0] + offsetof(CANDIDATELIST, dwCount)|
  DWORD count_data_offset = info->dwOffset[0];
  if (!SafeAdd(count_data_offset, offsetof(CANDIDATELIST, dwCount),
               count_data_offset)) {
    return false;
  }

  // |count_next_data_offset = count_data_offset + sizeof(DWORD)|
  DWORD count_next_data_offset = count_data_offset;
  if (!SafeAdd(count_next_data_offset, kSizeOfDWORD, count_next_data_offset)) {
    return false;
  }

  // Check if the target memory block has sufficient size to contain
  // CANDIDATELIST::dwCount.
  if (count_next_data_offset > buffer_size) {
    return false;
  }

  // Dereference the data.
  *count = *reinterpret_cast<const DWORD *>(
    reinterpret_cast<const BYTE *>(info) + count_data_offset);

  return true;
}

bool GetCandidateCount(HIMCC candidate_info_handle, DWORD *count) {
  if (candidate_info_handle == nullptr) {
    return false;
  }
  if (count == nullptr) {
    return false;
  }

  // If the target memory block does not have sufficient size, stop
  // reading the content.
  const DWORD buffer_size = ::ImmGetIMCCSize(candidate_info_handle);
  if (buffer_size < kSizeOfCANDIDATEINFO) {
    return false;
  }

  const CANDIDATEINFO *info =
      static_cast<CANDIDATEINFO *>(::ImmLockIMCC(candidate_info_handle));
  if (info == nullptr) {
    return false;
  }

  const bool result = GetCandidateCountInternal(info, buffer_size, count);
  ::ImmUnlockIMCC(candidate_info_handle);
  return result;
}
}  // anonymous namespace

CandidateInfo::CandidateInfo()
    : candidate_info_size(0),
      candidate_list_size(0),
      count(0),
      selection(0),
      show_candidate(false) {}

void CandidateInfo::Clear() {
  candidate_info_size = 0;
  candidate_list_size = 0;
  count = 0;
  selection = 0;
  show_candidate = false;
  offsets.clear();
  text_buffer.clear();
}

void CandidateInfoUtil::SetSafeDefault(CandidateInfo *info) {
  DCHECK_NE(nullptr, info);
  info->Clear();
  info->candidate_info_size = kSizeOfCANDIDATEINFOAndCANDIDATELIST;
  info->candidate_list_size = kSizeOfCANDIDATELIST;
  info->offsets.push_back(0);
}

bool CandidateInfoUtil::Convert(const mozc::commands::Output &output,
                                CandidateInfo *info) {
  if (info == nullptr) {
    return false;
  }
  info->Clear();

  // Note that |output.all_candidate_words()| delivers the result of the
  // latest activities in the server while |output.candidates()| reflects an
  // expected content of the candidate-window-like UI.  Here is an example to
  // explain the difference between |output.all_candidate_words()| and
  // |output.candidates()|
  //   1. Type "あ"
  //       -> |all_candidate_words()| == empty
  //       -> |candidates()| == empty
  //   2. Hit space to convert.
  //       -> |all_candidate_words()| == [CONVERSION: "あ", "吾", ...]
  //       -> |candidates()| == empty
  //          (candidate window is still invisible)
  //   3. Hit space again.
  //       -> |all_candidate_words()| == [CONVERSION: "あ", "吾", ...]
  //       -> |candidates()|  == [CONVERSION: "あ", "吾", ...]
  //          (candidate window shows up)
  // As filed in b/2978825, candidate list should be updated when and only
  // when the candidate window is visible.  This is why |output.candidates()|
  // is used here.
  if (!output.has_candidates()) {
    return true;
  }

  const Candidates &candidates = output.candidates();
  if (candidates.has_category() &&
      (candidates.category() == mozc::commands::SUGGESTION)) {
    // If this is a suggest UI popup, we will not update the candidate info.
    return true;
  }

  // Even though the update timing should be determined by the availability of
  // |output.candidates()|, |output.all_candidate_words()| is preferable to
  // fill the candidate list itself because it contains all of the candidates
  // as opposed to |output.candidates()| which contains candidates which is in
  // the current page.
  if (!output.has_all_candidate_words()) {
    return false;
  }

  const CandidateList &candidate_list = output.all_candidate_words();

  if (!candidate_list.has_focused_index()) {
    return false;
  }

  if (!SafeCast(candidate_list.candidates_size(), info->count)) {
    return false;
  }

  DCHECK(candidate_list.has_focused_index());
  info->selection = candidate_list.focused_index();

  // |offset_buffer_size = sizeof(DWORD) * info.count|
  DWORD offset_buffer_size = 0;
  if (!SafeMultiply(kSizeOfDWORD, info->count, offset_buffer_size)) {
    return false;
  }

  // |text_buffer_initial_offset =
  //      sizeof(CANDIDATELIST) - sizeof(DWORD) + offset_buffer_size|
  DWORD text_buffer_initial_offset = kSizeOfCANDIDATELISTHeader;
  if (!SafeAdd(text_buffer_initial_offset, offset_buffer_size,
               text_buffer_initial_offset)) {
    return false;
  }

  DWORD text_buffer_size = 0;
  for (size_t i = 0; i < candidate_list.candidates_size(); ++i) {
    // Calculates the offset from the top of CANDIDATELIST.
    DWORD offset = text_buffer_initial_offset;
    if (!SafeAdd(offset, text_buffer_size, offset)) {
      return false;
    }
    info->offsets.push_back(offset);

    wstring value;
    if (mozc::Util::UTF8ToWide(candidate_list.candidates(i).value(), &value) ==
        0) {
      value.clear();
    }

    // Add '\0'
    value += L'\0';

    DWORD text_len = 0;
    // |text_len = sizeof(wchar_t) * value.size()|
    if (!SafeMultiply(kSizeOfWCHAR, value.size(), text_len)) {
      return false;
    }
    // |text_buffer_size += text_len|
    if (!SafeAdd(text_buffer_size, text_len, text_buffer_size)) {
      return false;
    }
    for (size_t char_index = 0; char_index < value.size(); ++char_index) {
      info->text_buffer.push_back(value[char_index]);
    }
  }

  // |candidate_list_size = (sizeof(CANDIDATELIST) - sizeof(DWORD))|
  DWORD candidate_list_size = kSizeOfCANDIDATELISTHeader;
  // |candidate_list_size += offset_buffer_size|
  if (!SafeAdd(candidate_list_size, offset_buffer_size, candidate_list_size)) {
    return false;
  }
  // |candidate_list_size += text_buffer_size|
  if (!SafeAdd(candidate_list_size, text_buffer_size, candidate_list_size)) {
    return false;
  }

  // |candidate_info_size = sizeof(CANDIDATEINFO)|
  DWORD candidate_info_size = kSizeOfCANDIDATEINFO;
  // |candidate_info_size += candidate_list_size|
  if (!SafeAdd(candidate_info_size, candidate_list_size, candidate_info_size)) {
    return false;
  }

  info->candidate_info_size = candidate_info_size;
  info->candidate_list_size = candidate_list_size;
  info->show_candidate = true;
  return true;
}

void CandidateInfoUtil::Write(const CandidateInfo &info,
                              CANDIDATEINFO *target) {
  if (target == nullptr) {
    return;
  }

  target->dwSize = info.candidate_info_size;
  if (info.candidate_list_size == 0) {
    target->dwCount = 0;
    target->dwPrivateOffset = 0;
    target->dwPrivateSize = 0;
    for (size_t i = 0; i < arraysize(target->dwOffset); ++i) {
      target->dwOffset[i] = 0;
    }
    return;
  }

  target->dwCount = 1;  // Only 1 Candidate Window
  target->dwPrivateOffset = 0;
  target->dwPrivateSize = 0;
  target->dwOffset[0] = kSizeOfCANDIDATEINFO;

  for (size_t i = 1; i < arraysize(target->dwOffset); ++i) {
    // CANDIDATELIST is to be placed just after CANDIDATEINFO.
    target->dwOffset[i] = 0;
  }

  CANDIDATELIST *candidate_list =
      reinterpret_cast<CANDIDATELIST *>(reinterpret_cast<BYTE *>(target) +
                                        kSizeOfCANDIDATEINFO);

  candidate_list->dwSize = info.candidate_list_size;
  candidate_list->dwStyle = IME_CAND_READ;
  candidate_list->dwCount = info.count;
  candidate_list->dwSelection = info.selection;
  // Emulate dwPageStart to work around b/4077022 because Mozc server
  // does not support paging. See b/1855733
  // Note that IMM32 Office IME 2010 sets 0 to |dwPageStart| unless
  // it receives NI_SETCANDIDATE_PAGESTART.
  // TODO(yukawa): Investigate further.
  candidate_list->dwPageStart =
      (info.selection / kSafePageSize) * kSafePageSize;
  candidate_list->dwPageSize = kSafePageSize;

  if (info.count > 0) {
    DWORD *offsets = &candidate_list->dwOffset[0];
    wchar_t *text_buffer = reinterpret_cast<wchar_t *>(
        reinterpret_cast<BYTE *>(candidate_list) + info.offsets[0]);
    copy(info.offsets.begin(), info.offsets.end(), offsets);
    copy(info.text_buffer.begin(), info.text_buffer.end(), text_buffer);
  }
}

HIMCC CandidateInfoUtil::Initialize(HIMCC current_handle) {
  CandidateInfo info;
  SetSafeDefault(&info);

  return UpdateCandidateInfo(current_handle, info);
}

HIMCC CandidateInfoUtil::Update(HIMCC current_handle,
                                const mozc::commands::Output &output,
                                vector<UIMessage> *messages) {
  CandidateInfo info;
  Convert(output, &info);

  // If the data is not initialized or too small for some reason,
  // replace it with harmful data just in case.
  if (info.candidate_info_size < kSizeOfCANDIDATEINFOAndCANDIDATELIST) {
    SetSafeDefault(&info);
  }

  bool was_empty = true;
  if (current_handle != nullptr) {
    DWORD previous_count = 0;
    if (GetCandidateCount(current_handle, &previous_count) &&
        previous_count != 0) {
      was_empty = false;
    }
  }

  HIMCC new_handle = UpdateCandidateInfo(current_handle, info);

  if (messages != nullptr) {
    if (was_empty && info.show_candidate) {
      messages->push_back(UIMessage(WM_IME_NOTIFY, IMN_OPENCANDIDATE, 1));
    }

    if (!was_empty && info.show_candidate) {
      messages->push_back(UIMessage(WM_IME_NOTIFY, IMN_CHANGECANDIDATE, 1));
    }

    if (!was_empty && !info.show_candidate) {
      messages->push_back(UIMessage(WM_IME_NOTIFY, IMN_CLOSECANDIDATE, 1));
    }
  }

  return new_handle;
}

HIMCC CandidateInfoUtil::UpdateCandidateInfo(
    HIMCC current_handle, const CandidateInfo &list) {
  DCHECK_GE(list.candidate_info_size, kSizeOfCANDIDATEINFOAndCANDIDATELIST);

  HIMCC new_handle = nullptr;
  if (current_handle == nullptr) {
    new_handle = ::ImmCreateIMCC(list.candidate_info_size);
  } else {
    new_handle = ::ImmReSizeIMCC(current_handle, list.candidate_info_size);
  }

  if (new_handle != nullptr) {
    CANDIDATEINFO *buffer =
        static_cast<CANDIDATEINFO *>(::ImmLockIMCC(new_handle));
    if (buffer != nullptr) {
      Write(list, buffer);
      ::ImmUnlockIMCC(new_handle);
    }
  }
  return new_handle;
}
}  // namespace win32
}  // namespace mozc
