// Copyright 2021 The Chromium OS 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 "ml/web_platform_handwriting_proto_mojom_conversion.h"

#include <string>
#include <utility>

#include <base/time/time.h>
#include <gtest/gtest.h>

#include "ml/handwriting.h"

namespace ml {

using chromeos::machine_learning::web_platform::mojom::HandwritingHints;
using chromeos::machine_learning::web_platform::mojom::HandwritingPoint;
using chromeos::machine_learning::web_platform::mojom::HandwritingStroke;
using chromeos::machine_learning::web_platform::mojom::HandwritingStrokePtr;
using gfx::mojom::PointF;

// Tests `WebPlatformHandwritingStrokesAndHintsToProto` works correctly.
TEST(WebPlatformHandwritingProtoMojoConversionTest,
     HandwritingStrokesAndHintsToProto) {
  // Generate some strokes.
  std::vector<HandwritingStrokePtr> strokes;
  auto stroke1 = HandwritingStroke::New();
  stroke1->points.push_back(HandwritingPoint::New(
      PointF::New(1., 2.), base::TimeDelta::FromMilliseconds(3)));
  stroke1->points.push_back(HandwritingPoint::New(
      PointF::New(4., 5.), base::TimeDelta::FromMilliseconds(6)));
  auto stroke2 = HandwritingStroke::New();
  stroke2->points.push_back(HandwritingPoint::New(
      PointF::New(7., 8.), base::TimeDelta::FromMilliseconds(9)));
  strokes.push_back(std::move(stroke1));
  strokes.push_back(std::move(stroke2));

  auto hints = HandwritingHints::New("text", "mouse", "context", 100u);

  const auto proto = WebPlatformHandwritingStrokesAndHintsToProto(
      std::move(strokes), std::move(hints));

  // Checks correctness.
  // Checks correctness of ink.
  ASSERT_TRUE(proto.has_ink());
  // Checks the first stroke.
  EXPECT_EQ(proto.ink().strokes().size(), 2u);
  ASSERT_EQ(proto.ink().strokes()[0].points().size(), 2u);
  ASSERT_TRUE(proto.ink().strokes()[0].points()[0].has_x());
  EXPECT_EQ(proto.ink().strokes()[0].points()[0].x(), 1.);
  ASSERT_TRUE(proto.ink().strokes()[0].points()[0].has_y());
  EXPECT_EQ(proto.ink().strokes()[0].points()[0].y(), 2.);
  ASSERT_TRUE(proto.ink().strokes()[0].points()[0].has_t());
  EXPECT_EQ(proto.ink().strokes()[0].points()[0].t(), 3);
  ASSERT_TRUE(proto.ink().strokes()[0].points()[1].has_x());
  EXPECT_EQ(proto.ink().strokes()[0].points()[1].x(), 4.);
  ASSERT_TRUE(proto.ink().strokes()[0].points()[1].has_y());
  EXPECT_EQ(proto.ink().strokes()[0].points()[1].y(), 5.);
  ASSERT_TRUE(proto.ink().strokes()[0].points()[1].has_t());
  EXPECT_EQ(proto.ink().strokes()[0].points()[1].t(), 6);
  // Checks the second stroke.
  ASSERT_EQ(proto.ink().strokes()[1].points().size(), 1u);
  ASSERT_TRUE(proto.ink().strokes()[1].points()[0].has_x());
  EXPECT_EQ(proto.ink().strokes()[1].points()[0].x(), 7.);
  ASSERT_TRUE(proto.ink().strokes()[1].points()[0].has_y());
  EXPECT_EQ(proto.ink().strokes()[1].points()[0].y(), 8.);
  ASSERT_TRUE(proto.ink().strokes()[1].points()[0].has_t());
  EXPECT_EQ(proto.ink().strokes()[1].points()[0].t(), 9);

  ASSERT_TRUE(proto.context().has_pre_context());
  EXPECT_EQ(proto.context().pre_context(), "context");
  // Currently, we do not support writing guide.
  ASSERT_FALSE(proto.context().has_writing_guide());
  ASSERT_TRUE(proto.has_max_num_results());
  EXPECT_EQ(proto.max_num_results(), 100u);
  // We always ask for segmentation for HWR API.
  ASSERT_TRUE(proto.has_return_segmentation());
  EXPECT_TRUE(proto.return_segmentation());
}

// Tests `WebPlatformHandwritingPredictionsFromProto` works correctly.
TEST(WebPlatformHandwritingProtoMojoConversionTest,
     HandwritingPredictionsFromProto) {
  // Generates some strokes.
  std::vector<HandwritingStrokePtr> strokes;
  auto stroke1 = HandwritingStroke::New();
  stroke1->points.push_back(HandwritingPoint::New(
      PointF::New(11., 12.), base::TimeDelta::FromMilliseconds(13)));
  stroke1->points.push_back(HandwritingPoint::New(
      PointF::New(14., 15.), base::TimeDelta::FromMilliseconds(16)));
  auto stroke2 = HandwritingStroke::New();
  stroke2->points.push_back(HandwritingPoint::New(
      PointF::New(17., 18.), base::TimeDelta::FromMilliseconds(19)));
  strokes.push_back(std::move(stroke1));
  strokes.push_back(std::move(stroke2));

  // Generates recognition result proto.
  chrome_knowledge::HandwritingRecognizerCandidate candidate;
  candidate.set_text("recognition result");
  auto* const segmentation = candidate.mutable_segmentation();
  auto* const segment = segmentation->add_segments();
  segment->set_sublabel("sublabel");
  auto* const ink_range = segment->add_ink_ranges();
  ink_range->set_start_stroke(0);
  ink_range->set_end_stroke(1);
  ink_range->set_start_point(1);
  ink_range->set_end_point(0);
  chrome_knowledge::HandwritingRecognizerResult proto;
  *proto.add_candidates() = candidate;

  // First tries an empty input strokes and it should return base::nullopt.
  const auto predictions_empty_input_stroke =
      WebPlatformHandwritingPredictionsFromProto({}, proto);
  EXPECT_FALSE(predictions_empty_input_stroke.has_value());

  // Now input valid strokes.
  const auto optional_predictions =
      WebPlatformHandwritingPredictionsFromProto(strokes, proto);

  ASSERT_TRUE(optional_predictions.has_value());

  const auto& predictions = optional_predictions.value();
  ASSERT_EQ(predictions.size(), 1u);
  EXPECT_EQ(predictions[0]->text, "recognition result");
  ASSERT_EQ(predictions[0]->segmentation_result.size(), 1u);
  EXPECT_EQ(predictions[0]->segmentation_result[0]->grapheme, "sublabel");
  EXPECT_EQ(predictions[0]->segmentation_result[0]->begin_index, 0u);
  EXPECT_EQ(predictions[0]->segmentation_result[0]->end_index, 8u);
  ASSERT_EQ(predictions[0]->segmentation_result[0]->drawing_segments.size(),
            2u);
  EXPECT_EQ(
      predictions[0]->segmentation_result[0]->drawing_segments[0]->stroke_index,
      0u);
  EXPECT_EQ(predictions[0]
                ->segmentation_result[0]
                ->drawing_segments[0]
                ->begin_point_index,
            1u);
  EXPECT_EQ(predictions[0]
                ->segmentation_result[0]
                ->drawing_segments[0]
                ->end_point_index,
            2u);
  EXPECT_EQ(
      predictions[0]->segmentation_result[0]->drawing_segments[1]->stroke_index,
      1u);
  EXPECT_EQ(predictions[0]
                ->segmentation_result[0]
                ->drawing_segments[1]
                ->begin_point_index,
            0u);
  EXPECT_EQ(predictions[0]
                ->segmentation_result[0]
                ->drawing_segments[1]
                ->end_point_index,
            1u);
}

}  // namespace ml
