// Copyright 2018 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 <memory>
#include <utility>

#include <base/run_loop.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <mojo/public/cpp/bindings/binding.h>

#include "media_perception/fake_rtanalytics.h"
#include "media_perception/frame_perception.pb.h"
#include "media_perception/hotword_detection.pb.h"
#include "media_perception/output_manager.h"
#include "media_perception/presence_perception.pb.h"
#include "media_perception/proto_mojom_conversion.h"
#include "media_perception/serialized_proto.h"

namespace mri {
namespace {

class FramePerceptionHandlerImpl
    : public chromeos::media_perception::mojom::FramePerceptionHandler {
 public:
  FramePerceptionHandlerImpl(
      chromeos::media_perception::mojom::FramePerceptionHandlerRequest request)
      : binding_(this, std::move(request)) {
    EXPECT_TRUE(binding_.is_bound());
  }

  void OnFramePerception(chromeos::media_perception::mojom::FramePerceptionPtr
                             frame_perception) override {
    frame_perception_ = ToProto(frame_perception);
  }

  FramePerception frame_perception_;

  mojo::Binding<chromeos::media_perception::mojom::FramePerceptionHandler>
      binding_;
};

class HotwordDetectionHandlerImpl
    : public chromeos::media_perception::mojom::HotwordDetectionHandler {
 public:
  HotwordDetectionHandlerImpl(
      chromeos::media_perception::mojom::HotwordDetectionHandlerRequest request)
      : binding_(this, std::move(request)) {
    EXPECT_TRUE(binding_.is_bound());
  }

  void OnHotwordDetection(chromeos::media_perception::mojom::HotwordDetectionPtr
                              hotword_detection) override {
    hotword_detection_ = ToProto(hotword_detection);
  }

  HotwordDetection hotword_detection_;

  mojo::Binding<chromeos::media_perception::mojom::HotwordDetectionHandler>
      binding_;
};

class PresencePerceptionHandlerImpl
    : public chromeos::media_perception::mojom::PresencePerceptionHandler {
 public:
  PresencePerceptionHandlerImpl(
      chromeos::media_perception::mojom::PresencePerceptionHandlerRequest
          request)
      : binding_(this, std::move(request)) {
    EXPECT_TRUE(binding_.is_bound());
  }

  void OnPresencePerception(
      chromeos::media_perception::mojom::PresencePerceptionPtr
          presence_perception) override {
    presence_perception_ = ToProto(presence_perception);
  }

  PresencePerception presence_perception_;

  mojo::Binding<chromeos::media_perception::mojom::PresencePerceptionHandler>
      binding_;
};

class OccupancyTriggerHandlerImpl
    : public chromeos::media_perception::mojom::OccupancyTriggerHandler {
 public:
  OccupancyTriggerHandlerImpl(
      chromeos::media_perception::mojom::OccupancyTriggerHandlerRequest request)
      : binding_(this, std::move(request)) {
    EXPECT_TRUE(binding_.is_bound());
  }

  void OnOccupancyTrigger(chromeos::media_perception::mojom::OccupancyTriggerPtr
                              occupancy_trigger) override {
    occupancy_trigger_ = ToProto(occupancy_trigger);
  }

  OccupancyTrigger occupancy_trigger_;

  mojo::Binding<chromeos::media_perception::mojom::OccupancyTriggerHandler>
      binding_;
};

class AppearancesHandlerImpl
    : public chromeos::media_perception::mojom::AppearancesHandler {
 public:
  AppearancesHandlerImpl(
      chromeos::media_perception::mojom::AppearancesHandlerRequest request)
      : binding_(this, std::move(request)) {
    EXPECT_TRUE(binding_.is_bound());
  }

  void OnAppearances(const std::vector<uint8_t>& appearances) override {
    appearances_ = appearances;
  }

  std::vector<uint8_t> appearances_;

  mojo::Binding<chromeos::media_perception::mojom::AppearancesHandler> binding_;
};

class OneTouchAutozoomHandlerImpl
    : public chromeos::media_perception::mojom::OneTouchAutozoomHandler {
 public:
  OneTouchAutozoomHandlerImpl(
      chromeos::media_perception::mojom::OneTouchAutozoomHandlerRequest request)
      : binding_(this, std::move(request)) {
    EXPECT_TRUE(binding_.is_bound());
  }

  void OnSmartFraming(const std::vector<uint8_t>& smart_framing) override {
    smart_framing_ = smart_framing;
  }

  std::vector<uint8_t> smart_framing_;

  mojo::Binding<chromeos::media_perception::mojom::OneTouchAutozoomHandler>
      binding_;
};

class SoftwareAutozoomHandlerImpl
    : public chromeos::media_perception::mojom::SoftwareAutozoomHandler {
 public:
  SoftwareAutozoomHandlerImpl(
      chromeos::media_perception::mojom::SoftwareAutozoomHandlerRequest request)
      : binding_(this, std::move(request)) {
    EXPECT_TRUE(binding_.is_bound());
  }

  void OnSmartFraming(const std::vector<uint8_t>& smart_framing) override {
    smart_framing_ = smart_framing;
  }

  std::vector<uint8_t> smart_framing_;

  mojo::Binding<chromeos::media_perception::mojom::SoftwareAutozoomHandler>
      binding_;
};

class OutputManagerTest : public testing::Test {
 protected:
  void SetUp() override {
    fake_rtanalytics_ = new FakeRtanalytics();
    rtanalytics_ = std::shared_ptr<Rtanalytics>(fake_rtanalytics_);
  }

  FakeRtanalytics* fake_rtanalytics_;
  std::shared_ptr<Rtanalytics> rtanalytics_;
};

TEST_F(OutputManagerTest, FramePerceptionOutputManagerTest) {
  PerceptionInterfaces perception_interfaces;
  PerceptionInterface* interface = perception_interfaces.add_interface();
  interface->set_interface_type(
      PerceptionInterfaceType::INTERFACE_FRAME_PERCEPTION);
  PipelineOutput* output = interface->add_output();
  output->set_output_type(PipelineOutputType::OUTPUT_FRAME_PERCEPTION);
  output->set_stream_name("fake_stream_name");

  chromeos::media_perception::mojom::PerceptionInterfacesPtr interfaces_ptr =
      chromeos::media_perception::mojom::PerceptionInterfaces::New();
  OutputManager output_manager("fake_frame_perception_configuration",
                               rtanalytics_, perception_interfaces,
                               &interfaces_ptr);
  // Verify that the mojo interface was created correctly.
  EXPECT_TRUE(interfaces_ptr->frame_perception_handler_request.is_pending());
  EXPECT_EQ(fake_rtanalytics_->GetMostRecentOutputStreamName(),
            "fake_stream_name");

  FramePerceptionHandlerImpl frame_perception_handler_impl(
      std::move(interfaces_ptr->frame_perception_handler_request));
  base::RunLoop().RunUntilIdle();

  FramePerception frame_perception;
  frame_perception.set_frame_id(1);
  output_manager.HandleFramePerception(
      Serialized<FramePerception>(frame_perception).GetBytes());
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(frame_perception_handler_impl.frame_perception_.frame_id(), 1);
}

TEST_F(OutputManagerTest, HotwordDetectionOutputManagerTest) {
  PerceptionInterfaces perception_interfaces;
  PerceptionInterface* interface = perception_interfaces.add_interface();
  interface->set_interface_type(
      PerceptionInterfaceType::INTERFACE_HOTWORD_DETECTION);
  PipelineOutput* output = interface->add_output();
  output->set_output_type(PipelineOutputType::OUTPUT_HOTWORD_DETECTION);
  output->set_stream_name("fake_stream_name");

  chromeos::media_perception::mojom::PerceptionInterfacesPtr interfaces_ptr =
      chromeos::media_perception::mojom::PerceptionInterfaces::New();
  OutputManager output_manager("fake_hotword_detection_configuration",
                               rtanalytics_, perception_interfaces,
                               &interfaces_ptr);
  // Verify that the mojo interface was created correctly.
  EXPECT_TRUE(interfaces_ptr->hotword_detection_handler_request.is_pending());
  EXPECT_EQ(fake_rtanalytics_->GetMostRecentOutputStreamName(),
            "fake_stream_name");

  HotwordDetectionHandlerImpl hotword_detection_handler_impl(
      std::move(interfaces_ptr->hotword_detection_handler_request));
  base::RunLoop().RunUntilIdle();

  HotwordDetection hotword_detection;
  hotword_detection.add_hotwords()->set_type(HotwordType::OK_GOOGLE);
  output_manager.HandleHotwordDetection(
      Serialized<HotwordDetection>(hotword_detection).GetBytes());
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(
      hotword_detection_handler_impl.hotword_detection_.hotwords(0).type(),
      HotwordType::OK_GOOGLE);
}

TEST_F(OutputManagerTest, PresencePerceptionOutputManagerTest) {
  PerceptionInterfaces perception_interfaces;
  PerceptionInterface* interface = perception_interfaces.add_interface();
  interface->set_interface_type(
      PerceptionInterfaceType::INTERFACE_PRESENCE_PERCEPTION);
  PipelineOutput* output = interface->add_output();
  output->set_output_type(PipelineOutputType::OUTPUT_PRESENCE_PERCEPTION);
  output->set_stream_name("fake_stream_name");

  chromeos::media_perception::mojom::PerceptionInterfacesPtr interfaces_ptr =
      chromeos::media_perception::mojom::PerceptionInterfaces::New();
  OutputManager output_manager("fake_presence_perception_configuration",
                               rtanalytics_, perception_interfaces,
                               &interfaces_ptr);
  // Verify that the mojo interface was created correctly.
  EXPECT_TRUE(interfaces_ptr->presence_perception_handler_request.is_pending());
  EXPECT_EQ(fake_rtanalytics_->GetMostRecentOutputStreamName(),
            "fake_stream_name");

  PresencePerceptionHandlerImpl presence_perception_handler_impl(
      std::move(interfaces_ptr->presence_perception_handler_request));
  base::RunLoop().RunUntilIdle();

  PresencePerception presence_perception;
  presence_perception.set_timestamp_us(1);
  output_manager.HandlePresencePerception(
      Serialized<PresencePerception>(presence_perception).GetBytes());
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(
      presence_perception_handler_impl.presence_perception_.timestamp_us(), 1);
}

TEST_F(OutputManagerTest, OccupancyTriggerOutputManagerTest) {
  PerceptionInterfaces perception_interfaces;
  PerceptionInterface* interface = perception_interfaces.add_interface();
  interface->set_interface_type(
      PerceptionInterfaceType::INTERFACE_OCCUPANCY_TRIGGER);
  PipelineOutput* output = interface->add_output();
  output->set_output_type(PipelineOutputType::OUTPUT_OCCUPANCY_TRIGGER);
  output->set_stream_name("fake_stream_name");

  chromeos::media_perception::mojom::PerceptionInterfacesPtr interfaces_ptr =
      chromeos::media_perception::mojom::PerceptionInterfaces::New();
  OutputManager output_manager("fake_presence_perception_configuration",
                               rtanalytics_, perception_interfaces,
                               &interfaces_ptr);
  // Verify that the mojo interface was created correctly.
  EXPECT_TRUE(interfaces_ptr->occupancy_trigger_handler_request.is_pending());
  EXPECT_EQ(fake_rtanalytics_->GetMostRecentOutputStreamName(),
            "fake_stream_name");

  OccupancyTriggerHandlerImpl occupancy_trigger_handler_impl(
      std::move(interfaces_ptr->occupancy_trigger_handler_request));
  base::RunLoop().RunUntilIdle();

  OccupancyTrigger occupancy_trigger;
  occupancy_trigger.set_trigger(true);
  output_manager.HandleOccupancyTrigger(
      Serialized<OccupancyTrigger>(occupancy_trigger).GetBytes());
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(occupancy_trigger_handler_impl.occupancy_trigger_.trigger(), true);
}

TEST_F(OutputManagerTest, AppearancesOutputManagerTest) {
  PerceptionInterfaces perception_interfaces;
  PerceptionInterface* interface = perception_interfaces.add_interface();
  interface->set_interface_type(PerceptionInterfaceType::INTERFACE_APPEARANCES);
  PipelineOutput* output = interface->add_output();
  output->set_output_type(PipelineOutputType::OUTPUT_APPEARANCES);
  output->set_stream_name("fake_stream_name");

  chromeos::media_perception::mojom::PerceptionInterfacesPtr interfaces_ptr =
      chromeos::media_perception::mojom::PerceptionInterfaces::New();

  OutputManager output_manager("fake_presence_perception_configuration",
                               rtanalytics_, perception_interfaces,
                               &interfaces_ptr);

  EXPECT_TRUE(interfaces_ptr->appearances_handler_request.is_pending());
  EXPECT_EQ(fake_rtanalytics_->GetMostRecentOutputStreamName(),
            "fake_stream_name");

  AppearancesHandlerImpl appearances_handler_impl(
      std::move(interfaces_ptr->appearances_handler_request));
  base::RunLoop().RunUntilIdle();

  std::vector<uint8_t> bytes{0, 1, 2, 3, 1, 2, 3, 2, 1};

  output_manager.HandleAppearances(bytes);
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(appearances_handler_impl.appearances_.size(), bytes.size())
      << "Vectors are of unequal length.";

  for (int i = 0; i < bytes.size(); ++i) {
    EXPECT_EQ(appearances_handler_impl.appearances_[i], bytes[i])
        << "Bytes and Output Appearances Vector differ at index " << i;
  }
}

TEST_F(OutputManagerTest, OneTouchAutozoomOutputManagerTest) {
  PerceptionInterfaces perception_interfaces;
  PerceptionInterface* interface = perception_interfaces.add_interface();
  interface->set_interface_type(
      PerceptionInterfaceType::INTERFACE_ONE_TOUCH_AUTOZOOM);
  PipelineOutput* output = interface->add_output();
  output->set_output_type(PipelineOutputType::OUTPUT_SMART_FRAMING);
  output->set_stream_name("fake_stream_name");

  chromeos::media_perception::mojom::PerceptionInterfacesPtr interfaces_ptr =
      chromeos::media_perception::mojom::PerceptionInterfaces::New();

  OutputManager output_manager("fake_one_touch_autozoom_configuration",
                               rtanalytics_, perception_interfaces,
                               &interfaces_ptr);

  EXPECT_TRUE(interfaces_ptr->one_touch_autozoom_handler_request.is_pending());
  EXPECT_EQ(fake_rtanalytics_->GetMostRecentOutputStreamName(),
            "fake_stream_name");

  OneTouchAutozoomHandlerImpl one_touch_autozoom_handler_impl(
      std::move(interfaces_ptr->one_touch_autozoom_handler_request));
  base::RunLoop().RunUntilIdle();

  std::vector<uint8_t> bytes{0, 1, 2, 3, 1, 2, 3, 2, 1};

  output_manager.HandleSmartFraming(bytes);
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(one_touch_autozoom_handler_impl.smart_framing_.size(), bytes.size())
      << "Vectors are of unequal length.";

  for (int i = 0; i < bytes.size(); ++i) {
    EXPECT_EQ(one_touch_autozoom_handler_impl.smart_framing_[i], bytes[i])
        << "Bytes and Output Appearances Vector differ at index " << i;
  }
}

TEST_F(OutputManagerTest, SoftwareAutozoomOutputManagerTest) {
  PerceptionInterfaces perception_interfaces;
  PerceptionInterface* interface = perception_interfaces.add_interface();
  interface->set_interface_type(
      PerceptionInterfaceType::INTERFACE_SOFTWARE_AUTOZOOM);
  PipelineOutput* output = interface->add_output();
  output->set_output_type(PipelineOutputType::OUTPUT_SMART_FRAMING);
  output->set_stream_name("fake_stream_name");

  chromeos::media_perception::mojom::PerceptionInterfacesPtr interfaces_ptr =
      chromeos::media_perception::mojom::PerceptionInterfaces::New();

  OutputManager output_manager("fake_software_autozoom_configuration",
                               rtanalytics_, perception_interfaces,
                               &interfaces_ptr);

  EXPECT_TRUE(interfaces_ptr->software_autozoom_handler_request.is_pending());
  EXPECT_EQ(fake_rtanalytics_->GetMostRecentOutputStreamName(),
            "fake_stream_name");

  SoftwareAutozoomHandlerImpl software_autozoom_handler_impl(
      std::move(interfaces_ptr->software_autozoom_handler_request));
  base::RunLoop().RunUntilIdle();

  std::vector<uint8_t> bytes{0, 1, 2, 3, 1, 2, 3, 2, 1};

  output_manager.HandleSmartFraming(bytes);
  base::RunLoop().RunUntilIdle();

  ASSERT_EQ(software_autozoom_handler_impl.smart_framing_.size(), bytes.size())
      << "Vectors are of unequal length.";

  for (int i = 0; i < bytes.size(); ++i) {
    EXPECT_EQ(software_autozoom_handler_impl.smart_framing_[i], bytes[i])
        << "Bytes and Output Appearances Vector differ at index " << i;
  }
}

}  // namespace
}  // namespace mri
