// 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 "rewriter/calculator_rewriter.h"

#include <string>

#include "base/logging.h"
#include "base/scoped_ptr.h"
#include "base/system_util.h"
#include "config/config.pb.h"
#include "config/config_handler.h"
#include "converter/conversion_request.h"
#include "converter/converter_interface.h"
#include "converter/converter_mock.h"
#include "converter/segments.h"
#include "engine/engine_interface.h"
#include "engine/mock_data_engine_factory.h"
#include "rewriter/calculator/calculator_interface.h"
#include "rewriter/calculator/calculator_mock.h"
#include "session/commands.pb.h"
#include "testing/base/public/gunit.h"

DECLARE_string(test_tmpdir);

namespace mozc {
namespace {
void AddCandidate(const string &key, const string &value, Segment *segment) {
  Segment::Candidate *candidate = segment->add_candidate();
  candidate->Init();
  candidate->value = value;
  candidate->content_value = value;
  candidate->content_key = key;
}

void AddSegment(const string &key, const string &value, Segments *segments) {
  Segment *segment = segments->push_back_segment();
  segment->set_key(key);
  AddCandidate(key, value, segment);
}

void SetSegment(const string &key, const string &value, Segments *segments) {
  segments->Clear();
  AddSegment(key, value, segments);
}

// "計算結果"
const char kCalculationDescription[] =
    "\xE8\xA8\x88\xE7\xAE\x97\xE7\xB5\x90\xE6\x9E\x9C";

bool ContainsCalculatedResult(const Segment::Candidate &candidate) {
  return candidate.description.find(kCalculationDescription) != string::npos;
}

// If the segment has a candidate which was inserted by CalculatorRewriter,
// then return its index. Otherwise return -1.
int GetIndexOfCalculatedCandidate(const Segments &segments) {
  CHECK_EQ(segments.segments_size(), 1);
  for (size_t i = 0; i < segments.segment(0).candidates_size(); ++i) {
    const Segment::Candidate &candidate = segments.segment(0).candidate(i);
    if (ContainsCalculatedResult(candidate)) {
      return i;
    }
  }
  return -1;
}
}  // namespace

class CalculatorRewriterTest : public testing::Test {
 protected:
  static bool InsertCandidate(const CalculatorRewriter &calculator_rewriter,
                              const string &value,
                              size_t insert_pos,
                              Segment *segment) {
    return calculator_rewriter.InsertCandidate(value, insert_pos, segment);
  }

  CalculatorMock &calculator_mock() {
    return calculator_mock_;
  }

  CalculatorRewriter *BuildCalculatorRewriterWithConverterMock() {
    converter_mock_.reset(new ConverterMock);
    return new CalculatorRewriter(converter_mock_.get());
  }

  virtual void SetUp() {
    SystemUtil::SetUserProfileDirectory(FLAGS_test_tmpdir);

    // use mock
    CalculatorFactory::SetCalculator(&calculator_mock_);
    config::ConfigHandler::GetDefaultConfig(&default_config_);
    config::Config config(default_config_);
    config.set_use_calculator(true);
    config::ConfigHandler::SetConfig(config);
  }

  virtual void TearDown() {
    // Clear the mock test calculator
    CalculatorFactory::SetCalculator(NULL);
    config::ConfigHandler::SetConfig(default_config_);
  }

 private:
  CalculatorMock calculator_mock_;
  scoped_ptr<ConverterInterface> converter_mock_;
  config::Config default_config_;
};

TEST_F(CalculatorRewriterTest, InsertCandidateTest) {
  scoped_ptr<CalculatorRewriter> calculator_rewriter(
      BuildCalculatorRewriterWithConverterMock());

  {
    Segment segment;
    segment.set_key("key");
    // Insertion should be failed if segment has no candidate beforehand
    EXPECT_FALSE(InsertCandidate(*calculator_rewriter, "value", 0, &segment));
  }

  // Test insertion at each position of candidates list
  for (int i = 0; i <= 2; ++i) {
    Segment segment;
    segment.set_key("key");
    AddCandidate("key", "test", &segment);
    AddCandidate("key", "test2", &segment);

    EXPECT_TRUE(InsertCandidate(*calculator_rewriter, "value", i, &segment));
    const Segment::Candidate &candidate = segment.candidate(i);
    EXPECT_EQ(candidate.value, "value");
    EXPECT_EQ(candidate.content_value, "value");
    EXPECT_EQ(candidate.content_key, "key");
    EXPECT_NE(0, candidate.attributes & Segment::Candidate::NO_LEARNING);
    // Description should be "計算結果"
    EXPECT_EQ(candidate.description, kCalculationDescription);
  }
}

TEST_F(CalculatorRewriterTest, BasicTest) {
  // Pretend "key" is calculated to "value".
  calculator_mock().SetCalculatePair("key", "value", true);

  scoped_ptr<CalculatorRewriter> calculator_rewriter(
      BuildCalculatorRewriterWithConverterMock());
  const int counter_at_first = calculator_mock().calculation_counter();
  const ConversionRequest request;

  Segments segments;
  SetSegment("test", "test", &segments);
  calculator_rewriter->Rewrite(request, &segments);
  EXPECT_EQ(GetIndexOfCalculatedCandidate(segments), -1);
  EXPECT_EQ(calculator_mock().calculation_counter(), counter_at_first + 1);

  SetSegment("key", "key", &segments);
  calculator_rewriter->Rewrite(request, &segments);
  int index = GetIndexOfCalculatedCandidate(segments);
  EXPECT_NE(index, -1);
  EXPECT_EQ(segments.segment(0).candidate(index).value, "value");
  EXPECT_EQ(calculator_mock().calculation_counter(), counter_at_first + 2);
}

// CalculatorRewriter should convert an expression which is separated to
// multiple conversion segments. This test verifies it.
TEST_F(CalculatorRewriterTest, SeparatedSegmentsTest) {
  // Pretend "1+1=" is calculated to "2".
  calculator_mock().SetCalculatePair("1+1=", "2", true);

  // Since this test depends on the actual implementation of
  // Converter::ResizeSegments(), we cannot use converter mock here. However,
  // the test itself is independent of data.
  scoped_ptr<EngineInterface> engine_(MockDataEngineFactory::Create());
  scoped_ptr<CalculatorRewriter> calculator_rewriter(
      new CalculatorRewriter(engine_->GetConverter()));
  const ConversionRequest request;

  // Push back separated segments.
  Segments segments;
  AddSegment("1", "1", &segments);
  AddSegment("+", "+", &segments);
  AddSegment("1", "1", &segments);
  AddSegment("=", "=", &segments);

  calculator_rewriter->Rewrite(request, &segments);
  EXPECT_EQ(segments.segments_size(), 1);  // merged

  int index = GetIndexOfCalculatedCandidate(segments);
  EXPECT_NE(index, -1);

  // Secondary result with expression (description: "1+1=2");
  EXPECT_TRUE(ContainsCalculatedResult(
      segments.segment(0).candidate(index + 1)));

  EXPECT_EQ("2", segments.segment(0).candidate(index).value);
  EXPECT_EQ("1+1=2", segments.segment(0).candidate(index + 1).value);
}

// Verify the description of calculator candidate.
TEST_F(CalculatorRewriterTest, DescriptionCheckTest) {
  // "５・（８／４）ー７％３＋６＾−１＊９＝"
  const char kExpression[] =
      "\xEF\xBC\x95\xE3\x83\xBB\xEF\xBC\x88\xEF\xBC\x98\xEF\xBC\x8F"
      "\xEF\xBC\x94\xEF\xBC\x89\xE3\x83\xBC\xEF\xBC\x97\xEF\xBC\x85"
      "\xEF\xBC\x93\xEF\xBC\x8B\xEF\xBC\x96\xEF\xBC\xBE\xE2\x88\x92"
      "\xEF\xBC\x91\xEF\xBC\x8A\xEF\xBC\x99\xEF\xBC\x9D";
  // Expected description
  const string description = kCalculationDescription;

  // Pretend kExpression is calculated to "3"
  calculator_mock().SetCalculatePair(kExpression, "3", true);
  const ConversionRequest request;

  scoped_ptr<CalculatorRewriter> calculator_rewriter(
      BuildCalculatorRewriterWithConverterMock());

  Segments segments;
  AddSegment(kExpression, kExpression, &segments);

  calculator_rewriter->Rewrite(request, &segments);
  const int index = GetIndexOfCalculatedCandidate(segments);

  EXPECT_EQ(segments.segment(0).candidate(index).description, description);
  EXPECT_TRUE(ContainsCalculatedResult(
      segments.segment(0).candidate(index + 1)));
}

TEST_F(CalculatorRewriterTest, ConfigTest) {
  config::Config config;
  config::ConfigHandler::GetDefaultConfig(&config);

  calculator_mock().SetCalculatePair("1+1=", "2", true);
  const ConversionRequest request;

  // Since this test depends on the actual implementation of
  // Converter::ResizeSegments(), we cannot use converter mock here. However,
  // the test itself is independent of data.
  scoped_ptr<EngineInterface> engine_(MockDataEngineFactory::Create());
  scoped_ptr<CalculatorRewriter> calculator_rewriter(
      new CalculatorRewriter(engine_->GetConverter()));
  {
    Segments segments;
    AddSegment("1", "1", &segments);
    AddSegment("+", "+", &segments);
    AddSegment("1", "1", &segments);
    AddSegment("=", "=", &segments);
    config.set_use_calculator(true);
    config::ConfigHandler::SetConfig(config);
    EXPECT_TRUE(calculator_rewriter->Rewrite(request, &segments));
  }

  {
    Segments segments;
    AddSegment("1", "1", &segments);
    AddSegment("+", "+", &segments);
    AddSegment("1", "1", &segments);
    AddSegment("=", "=", &segments);
    config.set_use_calculator(false);
    config::ConfigHandler::SetConfig(config);
    EXPECT_FALSE(calculator_rewriter->Rewrite(request, &segments));
  }
}

TEST_F(CalculatorRewriterTest, MobileEnvironmentTest) {
  commands::Request input;
  scoped_ptr<EngineInterface> engine_(MockDataEngineFactory::Create());
  scoped_ptr<CalculatorRewriter> rewriter(
      new CalculatorRewriter(engine_->GetConverter()));

  {
    input.set_mixed_conversion(true);
    const ConversionRequest request(NULL, &input);
    EXPECT_EQ(RewriterInterface::ALL, rewriter->capability(request));
  }

  {
    input.set_mixed_conversion(false);
    const ConversionRequest request(NULL, &input);
    EXPECT_EQ(RewriterInterface::CONVERSION, rewriter->capability(request));
  }
}

TEST_F(CalculatorRewriterTest, EmptyKeyTest) {
  config::Config config;
  config::ConfigHandler::GetDefaultConfig(&config);

  const ConversionRequest request;
  scoped_ptr<EngineInterface> engine_(MockDataEngineFactory::Create());
  scoped_ptr<CalculatorRewriter> calculator_rewriter(
      new CalculatorRewriter(engine_->GetConverter()));
  {
    Segments segments;
    AddSegment("", "1", &segments);
    config.set_use_calculator(true);
    config::ConfigHandler::SetConfig(config);
    EXPECT_FALSE(calculator_rewriter->Rewrite(request, &segments));
  }
}

}  // namespace mozc
