// 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 "unix/ibus/surrounding_text_util.h"

#include <limits>
#include <string>

#include "base/logging.h"
#include "base/port.h"
#include "base/util.h"

namespace mozc {
namespace ibus {

bool SurroundingTextUtil::GetSafeDelta(guint from, guint to, int32 *delta) {
  DCHECK(delta);

  static_assert(sizeof(int64) >= sizeof(guint),
                "int64 must be sufficient to store a guint value.");
  static_assert(sizeof(int64) == sizeof(llabs(0)),
                "|llabs(0)| must returns a 64-bit integer.");
  const int64 kInt32AbsMax =
      llabs(static_cast<int64>(numeric_limits<int32>::max()));
  const int64 kInt32AbsMin =
      llabs(static_cast<int64>(numeric_limits<int32>::min()));
  const int64 kInt32SafeAbsMax =
      min(kInt32AbsMax, kInt32AbsMin);

  const int64 diff = static_cast<int64>(from) - static_cast<int64>(to);
  if (llabs(diff) > kInt32SafeAbsMax) {
    return false;
  }

  *delta = static_cast<int32>(diff);
  return true;
}

namespace {

// Moves |iter| with |skip_count| characters.
// Returns false if |iter| reaches to the end before skipping
// |skip_count| characters.
bool Skip(ConstChar32Iterator *iter, size_t skip_count) {
  for (size_t i = 0; i < skip_count; ++i) {
    if (iter->Done()) {
      return false;
    }
    iter->Next();
  }
  return true;
}

// Returns true if |prefix_iter| is the prefix of |iter|.
// Returns false if |prefix_iter| is an empty sequence.
// Otherwise returns false.
// This function receives ConstChar32Iterator as pointer because
// ConstChar32Iterator is defined as non-copyable.
bool StartsWith(ConstChar32Iterator *iter,
                ConstChar32Iterator *prefix_iter) {
  if (iter->Done() || prefix_iter->Done()) {
    return false;
  }

  while (true) {
    if (iter->Get() != prefix_iter->Get()) {
      return false;
    }
    prefix_iter->Next();
    if (prefix_iter->Done()) {
      return true;
    }
    iter->Next();
    if (iter->Done()) {
      return false;
    }
  }
}


// Returns true if |surrounding_text| contains |selected_text|
// from |cursor_pos| to |*anchor_pos|.
// Otherwise returns false.
bool SearchAnchorPosForward(
    const string &surrounding_text,
    const string &selected_text,
    size_t selected_chars_len,
    guint cursor_pos,
    guint *anchor_pos) {

  ConstChar32Iterator iter(surrounding_text);
  // Move |iter| to cursor pos.
  if (!Skip(&iter, cursor_pos)) {
    return false;
  }

  ConstChar32Iterator sel_iter(selected_text);
  if (!StartsWith(&iter, &sel_iter)) {
    return false;
  }
  *anchor_pos = cursor_pos + selected_chars_len;
  return true;
}

// Returns true if |surrounding_text| contains |selected_text|
// from |*anchor_pos| to |cursor_pos|.
// Otherwise returns false.
bool SearchAnchorPosBackward(
    const string &surrounding_text,
    const string &selected_text,
    size_t selected_chars_len,
    guint cursor_pos,
    guint *anchor_pos) {
  if (cursor_pos < selected_chars_len) {
    return false;
  }

  ConstChar32Iterator iter(surrounding_text);
  // Skip |iter| to (potential) anchor pos.
  const guint skip_count = cursor_pos - selected_chars_len;
  DCHECK_LE(skip_count, cursor_pos);
  if (!Skip(&iter, skip_count)) {
    return false;
  }

  ConstChar32Iterator sel_iter(selected_text);
  if (!StartsWith(&iter, &sel_iter)) {
    return false;
  }
  *anchor_pos = cursor_pos - selected_chars_len;
  return true;
}

}  // namespace

bool SurroundingTextUtil::GetAnchorPosFromSelection(
    const string &surrounding_text,
    const string &selected_text,
    guint cursor_pos,
    guint *anchor_pos) {
  DCHECK(anchor_pos);

  if (surrounding_text.empty()) {
    return false;
  }

  if (selected_text.empty()) {
    return false;
  }

  const size_t selected_chars_len = Util::CharsLen(selected_text);

  if (SearchAnchorPosForward(surrounding_text, selected_text,
                             selected_chars_len,
                             cursor_pos, anchor_pos)) {
    return true;
  }

  return SearchAnchorPosBackward(surrounding_text, selected_text,
                                 selected_chars_len,
                                 cursor_pos, anchor_pos);
}

}  // namespace ibus
}  // namespace mozc
