// 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 "media_perception/proto_mojom_conversion.h"

#include <gtest/gtest.h>
#include <string>
#include <utility>

const char kMockConfigurationName[] = "fake_configuration";
const char kMockErrorSource[] = "Mock Error Source";
const char kMockErrorString[] = "Mock Error String";

namespace {

constexpr int kNumSupportedConfigurations = 3;

}  // namespace

namespace chromeos {
namespace media_perception {
namespace mojom {

namespace {

mri::VideoStreamParams CreateVideoStreamParamsProto(
    int width_in_pixels,
    int height_in_pixels,
    float frame_rate_in_frames_per_second) {
  mri::VideoStreamParams params;
  params.set_width_in_pixels(width_in_pixels);
  params.set_height_in_pixels(height_in_pixels);
  params.set_frame_rate_in_frames_per_second(frame_rate_in_frames_per_second);
  params.set_pixel_format(mri::PixelFormat::I420);
  return params;
}

mri::VideoDevice CreateVideoDeviceProto(std::string id,
                                        std::string display_name,
                                        std::string model_id,
                                        bool in_use) {
  mri::VideoDevice device;
  device.set_id(id);
  device.set_display_name(display_name);
  device.set_model_id(model_id);
  for (int i = 0; i < kNumSupportedConfigurations; i++) {
    int j = i * kNumSupportedConfigurations;
    mri::VideoStreamParams* params = device.add_supported_configurations();
    *params = CreateVideoStreamParamsProto(j, j + 1, j + 2);
  }
  device.set_in_use(in_use);
  if (in_use) {
    mri::VideoStreamParams* params = device.mutable_configuration();
    *params = CreateVideoStreamParamsProto(1, 2, 3);
  }
  return device;
}

mri::AudioStreamParams CreateAudioStreamParamsProto(
    float frequency_in_hz,
    int num_channels,
    int frame_size,
    mri::SampleFormat sample_format) {
  mri::AudioStreamParams params;
  params.set_frequency_in_hz(frequency_in_hz);
  params.set_num_channels(num_channels);
  params.set_frame_size(frame_size);
  params.set_sample_format(sample_format);
  return params;
}

mri::AudioDevice CreateAudioDeviceProto(std::string id,
                                        std::string display_name) {
  mri::AudioDevice device;
  device.set_id(id);
  device.set_display_name(display_name);
  for (int i = 0; i < kNumSupportedConfigurations; i++) {
    int j = i * kNumSupportedConfigurations;
    mri::AudioStreamParams* params = device.add_supported_configurations();
    *params = CreateAudioStreamParamsProto(
        j, j + 1, j + 2, mri::SampleFormat::SND_PCM_FORMAT_S32_LE);
  }
  mri::AudioStreamParams* params = device.mutable_configuration();
  *params = CreateAudioStreamParamsProto(
      1, 2, 3, mri::SampleFormat::SND_PCM_FORMAT_S16_LE);
  return device;
}

TEST(ProtoMojomConversionTest, SuccessStatusToMojom) {
  mri::SuccessStatus status;
  status.set_success(false);
  status.set_failure_reason("failed");

  SuccessStatusPtr status_ptr = ToMojom(status);
  EXPECT_EQ(status_ptr->success, false);
  EXPECT_EQ(*status_ptr->failure_reason, "failed");
}

TEST(ProtoMojomConversionTest, VideoStreamParamsToMojom) {
  mri::VideoStreamParams params = CreateVideoStreamParamsProto(1, 2, 3);

  VideoStreamParamsPtr params_ptr = ToMojom(params);
  EXPECT_EQ(params_ptr->width_in_pixels, 1);
  EXPECT_EQ(params_ptr->height_in_pixels, 2);
  EXPECT_EQ(params_ptr->frame_rate_in_frames_per_second, 3);
  EXPECT_EQ(params_ptr->pixel_format, PixelFormat::I420);
}

TEST(ProtoMojomConversionTest, VideoDeviceToMojom) {
  mri::VideoDevice device =
      CreateVideoDeviceProto("id", "display_name", "model_id", true);

  VideoDevicePtr device_ptr = ToMojom(device);
  EXPECT_EQ(device_ptr->id, "id");
  EXPECT_EQ(*device_ptr->display_name, "display_name");
  EXPECT_EQ(*device_ptr->model_id, "model_id");
  EXPECT_EQ(device_ptr->in_use, true);
  EXPECT_EQ(device_ptr->configuration->width_in_pixels, 1);
  EXPECT_EQ(device_ptr->configuration->height_in_pixels, 2);
  EXPECT_EQ(device_ptr->configuration->frame_rate_in_frames_per_second, 3);
  EXPECT_EQ(device_ptr->configuration->pixel_format, PixelFormat::I420);
  EXPECT_EQ(device_ptr->supported_configurations.size(),
            kNumSupportedConfigurations);
  for (int i = 0; i < kNumSupportedConfigurations; i++) {
    EXPECT_EQ(device_ptr->supported_configurations[i]->width_in_pixels,
              i * kNumSupportedConfigurations);
  }
}

TEST(ProtoMojomConversionTest, VirtualVideoDeviceToMojom) {
  mri::VirtualVideoDevice device;
  mri::VideoDevice* video_device = device.mutable_video_device();
  *video_device =
      CreateVideoDeviceProto("id", "display_name", "model_id", true);
  VirtualVideoDevicePtr device_ptr = ToMojom(device);
  EXPECT_EQ(device_ptr->video_device->id, "id");
}

TEST(ProtoMojomConversionTest, AudioStreamParamsToMojom) {
  mri::AudioStreamParams params = CreateAudioStreamParamsProto(
      1, 2, 3, mri::SampleFormat::SND_PCM_FORMAT_S32_LE);
  AudioStreamParamsPtr params_ptr = ToMojom(params);
  EXPECT_EQ(params_ptr->frequency_in_hz, 1);
  EXPECT_EQ(params_ptr->num_channels, 2);
  EXPECT_EQ(params_ptr->frame_size, 3);
  EXPECT_EQ(params_ptr->sample_format, SampleFormat::SND_PCM_FORMAT_S32_LE);

  params = CreateAudioStreamParamsProto(
      1, 2, 3, mri::SampleFormat::SND_PCM_FORMAT_S16_LE);
  params_ptr = ToMojom(params);
  EXPECT_EQ(params_ptr->sample_format, SampleFormat::SND_PCM_FORMAT_S16_LE);
}

TEST(ProtoMojomConversionTest, AudioDeviceToMojom) {
  mri::AudioDevice device = CreateAudioDeviceProto("id", "display_name");
  AudioDevicePtr device_ptr = ToMojom(device);
  EXPECT_EQ(device_ptr->id, "id");
  EXPECT_EQ(*device_ptr->display_name, "display_name");
  EXPECT_EQ(device_ptr->configuration->frequency_in_hz, 1);
  EXPECT_EQ(device_ptr->configuration->num_channels, 2);
  EXPECT_EQ(device_ptr->supported_configurations.size(),
            kNumSupportedConfigurations);
  for (int i = 0; i < kNumSupportedConfigurations; i++) {
    EXPECT_EQ(device_ptr->supported_configurations[i]->frequency_in_hz,
              i * kNumSupportedConfigurations);
  }
}

TEST(ProtoMojomConversionTest, DeviceTemplateToMojom) {
  mri::DeviceTemplate device_template;
  device_template.set_template_name("template_name");
  device_template.set_device_type(mri::DeviceType::VIRTUAL_VIDEO);
  DeviceTemplatePtr template_ptr = ToMojom(device_template);
  EXPECT_EQ(template_ptr->template_name, "template_name");
  EXPECT_EQ(template_ptr->device_type, DeviceType::VIRTUAL_VIDEO);
}

TEST(ProtoMojomConversionTest, NormalizedBoundingBoxToMojom) {
  mri::NormalizedBoundingBox bbox;
  bbox.set_x_min(0.1);
  bbox.set_y_min(0.2);
  bbox.set_x_max(0.7);
  bbox.set_y_max(0.8);
  bbox.set_normalization_width(10);
  bbox.set_normalization_height(20);

  NormalizedBoundingBoxPtr bbox_ptr = ToMojom(bbox);
  EXPECT_FLOAT_EQ(bbox_ptr->x_min, 0.1);
  EXPECT_FLOAT_EQ(bbox_ptr->y_min, 0.2);
  EXPECT_FLOAT_EQ(bbox_ptr->x_max, 0.7);
  EXPECT_FLOAT_EQ(bbox_ptr->y_max, 0.8);
  EXPECT_EQ(bbox_ptr->normalization_width, 10);
  EXPECT_EQ(bbox_ptr->normalization_height, 20);
}

TEST(ProtoMojomConversionTest, DistanceToMojom) {
  mri::Distance distance;
  distance.set_units(mri::DistanceUnits::METERS);
  distance.set_magnitude(1.5);

  DistancePtr distance_ptr = ToMojom(distance);
  EXPECT_EQ(distance_ptr->units, DistanceUnits::METERS);
  EXPECT_FLOAT_EQ(distance_ptr->magnitude, 1.5);
}

TEST(ProtoMojomConversionTest, HotwordDetectionToMojom) {
  mri::HotwordDetection hotword_detection;

  mri::Hotword* hotword1 = hotword_detection.add_hotwords();
  hotword1->set_type(mri::HotwordType::OK_GOOGLE);
  hotword1->set_start_timestamp_ms(100);
  hotword1->set_end_timestamp_ms(250);

  mri::Hotword* hotword2 = hotword_detection.add_hotwords();
  hotword2->set_start_timestamp_ms(560);
  hotword2->set_end_timestamp_ms(700);

  HotwordDetectionPtr hotword_detection_ptr = ToMojom(hotword_detection);
  EXPECT_EQ(hotword_detection_ptr->hotwords.size(), 2);

  EXPECT_EQ(hotword_detection_ptr->hotwords[0]->type, HotwordType::OK_GOOGLE);
  EXPECT_EQ(hotword_detection_ptr->hotwords[0]->start_timestamp_ms, 100);
  EXPECT_EQ(hotword_detection_ptr->hotwords[0]->end_timestamp_ms, 250);

  EXPECT_EQ(hotword_detection_ptr->hotwords[1]->type,
            HotwordType::HOTWORD_TYPE_UNKNOWN);
  EXPECT_EQ(hotword_detection_ptr->hotwords[1]->start_timestamp_ms, 560);
  EXPECT_EQ(hotword_detection_ptr->hotwords[1]->end_timestamp_ms, 700);
}

TEST(ProtoMojomConversionTest, EntityToMojom) {
  mri::Entity entity;
  entity.set_type(mri::EntityType::FACE);
  entity.set_label("face 0");
  entity.set_confidence(0.1);
  entity.mutable_depth()->set_units(mri::DistanceUnits::METERS);
  entity.mutable_bounding_box()->set_x_min(0.2);

  EntityPtr entity_ptr = ToMojom(entity);
  EXPECT_EQ(entity_ptr->type, EntityType::FACE);
  EXPECT_EQ(*entity_ptr->label, "face 0");
  EXPECT_FLOAT_EQ(entity_ptr->confidence, 0.1);
  EXPECT_EQ(entity_ptr->depth->units, DistanceUnits::METERS);
  EXPECT_FLOAT_EQ(entity_ptr->bounding_box->x_min, 0.2);
}

TEST(ProtoMojomConversionTest, FramePerceptionToMojom) {
  mri::FramePerception perception;
  perception.set_frame_id(1);
  perception.set_timestamp_us(157);
  perception.add_perception_types(mri::FramePerceptionType::FACE_DETECTION);
  perception.add_perception_types(mri::FramePerceptionType::PERSON_DETECTION);
  perception.add_perception_types(mri::FramePerceptionType::MOTION_DETECTION);
  perception.add_entities()->set_type(mri::EntityType::FACE);
  perception.add_entities()->set_type(mri::EntityType::PERSON);
  perception.add_entities()->set_type(mri::EntityType::MOTION_REGION);
  perception.add_entities()->set_type(mri::EntityType::LABELED_REGION);

  FramePerceptionPtr perception_ptr = ToMojom(perception);
  EXPECT_EQ(perception_ptr->frame_id, 1);
  EXPECT_EQ(perception_ptr->timestamp_us, 157);
  EXPECT_EQ(perception_ptr->perception_types.size(), 3);
  EXPECT_EQ(perception_ptr->perception_types[0],
            FramePerceptionType::FACE_DETECTION);
  EXPECT_EQ(perception_ptr->perception_types[1],
            FramePerceptionType::PERSON_DETECTION);
  EXPECT_EQ(perception_ptr->perception_types[2],
            FramePerceptionType::MOTION_DETECTION);
  EXPECT_EQ(perception_ptr->entities.size(), 4);
  EXPECT_EQ(perception_ptr->entities[0]->type, EntityType::FACE);
  EXPECT_EQ(perception_ptr->entities[1]->type, EntityType::PERSON);
  EXPECT_EQ(perception_ptr->entities[2]->type, EntityType::MOTION_REGION);
  EXPECT_EQ(perception_ptr->entities[3]->type, EntityType::LABELED_REGION);
}

TEST(ProtoMojomConversionTest, PipelineErrorToMojom) {
  mri::PipelineError error;
  error.set_error_type(mri::PipelineErrorType::CONFIGURATION);
  error.set_error_source(kMockErrorSource);
  error.set_error_string(kMockErrorString);

  PipelineErrorPtr error_ptr = ToMojom(error);
  EXPECT_EQ(error_ptr->error_type, PipelineErrorType::CONFIGURATION);
  EXPECT_EQ(*error_ptr->error_source, kMockErrorSource);
  EXPECT_EQ(*error_ptr->error_string, kMockErrorString);
}

TEST(ProtoMojomConversionTest, PipelineStateToMojom) {
  mri::PipelineState state;
  state.set_configuration_name(kMockConfigurationName);
  state.set_status(mri::PipelineStatus::RUNNING);

  mri::PipelineError& error = *state.mutable_error();
  error.set_error_type(mri::PipelineErrorType::CONFIGURATION);
  error.set_error_source(kMockErrorSource);
  error.set_error_string(kMockErrorString);

  PipelineStatePtr state_ptr = ToMojom(state);
  EXPECT_EQ(state_ptr->status, PipelineStatus::RUNNING);
  EXPECT_EQ(*state_ptr->configuration_name, kMockConfigurationName);

  PipelineErrorPtr& error_ptr = state_ptr->error;
  EXPECT_EQ(error_ptr->error_type, PipelineErrorType::CONFIGURATION);
  EXPECT_EQ(*error_ptr->error_source, kMockErrorSource);
  EXPECT_EQ(*error_ptr->error_string, kMockErrorString);
}

TEST(ProtoMojomConversionTest, GlobalPipelineStateToMojom) {
  mri::GlobalPipelineState state;
  state.add_states()->set_configuration_name("0");
  state.add_states()->set_configuration_name("1");

  GlobalPipelineStatePtr state_ptr = ToMojom(state);
  EXPECT_EQ(*state_ptr->states[0]->configuration_name, "0");
  EXPECT_EQ(*state_ptr->states[1]->configuration_name, "1");
}

TEST(ProtoMojomConversionTest, PresencePerceptionToMojom) {
  mri::PresencePerception perception;
  perception.set_timestamp_us(100);
  perception.set_presence_confidence(0.5);

  PresencePerceptionPtr perception_ptr = ToMojom(perception);
  EXPECT_EQ(perception_ptr->timestamp_us, 100);
  EXPECT_FLOAT_EQ(perception_ptr->presence_confidence, 0.5);
}

TEST(ProtoMojomConversionTest, OccupancyTriggerToMojom) {
  mri::OccupancyTrigger occupancy_trigger;
  occupancy_trigger.set_trigger(true);
  occupancy_trigger.set_timestamp_ms(100);

  OccupancyTriggerPtr occupancy_ptr = ToMojom(occupancy_trigger);
  EXPECT_EQ(occupancy_ptr->trigger, true);
  EXPECT_EQ(occupancy_ptr->timestamp_ms, 100);
}

}  // namespace
}  // namespace mojom
}  // namespace media_perception
}  // namespace chromeos

namespace mri {
namespace {

chromeos::media_perception::mojom::VideoStreamParamsPtr
CreateVideoStreamParamsPtr(int width_in_pixels,
                           int height_in_pixels,
                           float frame_rate_in_frames_per_second) {
  chromeos::media_perception::mojom::VideoStreamParamsPtr params_ptr =
      chromeos::media_perception::mojom::VideoStreamParams::New();
  params_ptr->width_in_pixels = width_in_pixels;
  params_ptr->height_in_pixels = height_in_pixels;
  params_ptr->frame_rate_in_frames_per_second = frame_rate_in_frames_per_second;
  params_ptr->pixel_format =
      chromeos::media_perception::mojom::PixelFormat::I420;
  return params_ptr;
}

chromeos::media_perception::mojom::VideoDevicePtr CreateVideoDevicePtr(
    std::string id,
    std::string display_name,
    std::string model_id,
    bool in_use) {
  chromeos::media_perception::mojom::VideoDevicePtr device_ptr =
      chromeos::media_perception::mojom::VideoDevice::New();
  device_ptr->id = id;
  device_ptr->display_name = display_name;
  device_ptr->model_id = model_id;
  for (int i = 0; i < kNumSupportedConfigurations; i++) {
    int j = i * kNumSupportedConfigurations;
    device_ptr->supported_configurations.push_back(
        CreateVideoStreamParamsPtr(j, j + 1, j + 2));
  }
  device_ptr->in_use = in_use;
  if (in_use) {
    device_ptr->configuration = CreateVideoStreamParamsPtr(1, 2, 3);
  }
  return device_ptr;
}

chromeos::media_perception::mojom::AudioStreamParamsPtr
CreateAudioStreamParamsPtr(float frequency_in_hz,
                           int num_channels,
                           int frame_size) {
  chromeos::media_perception::mojom::AudioStreamParamsPtr params_ptr =
      chromeos::media_perception::mojom::AudioStreamParams::New();
  params_ptr->frequency_in_hz = frequency_in_hz;
  params_ptr->num_channels = num_channels;
  params_ptr->frame_size = frame_size;
  params_ptr->sample_format =
      chromeos::media_perception::mojom::SampleFormat::SND_PCM_FORMAT_S16_LE;
  return params_ptr;
}

chromeos::media_perception::mojom::AudioDevicePtr CreateAudioDevicePtr(
    std::string id, std::string display_name) {
  chromeos::media_perception::mojom::AudioDevicePtr device_ptr =
      chromeos::media_perception::mojom::AudioDevice::New();
  device_ptr->id = id;
  device_ptr->display_name = display_name;
  for (int i = 0; i < kNumSupportedConfigurations; i++) {
    int j = i * kNumSupportedConfigurations;
    device_ptr->supported_configurations.push_back(
        CreateAudioStreamParamsPtr(j, j + 1, j + 2));
  }
  device_ptr->configuration = CreateAudioStreamParamsPtr(1, 2, 3);
  return device_ptr;
}

TEST(ProtoMojomConversionTest, SuccessStatusToProto) {
  chromeos::media_perception::mojom::SuccessStatusPtr status_ptr =
      chromeos::media_perception::mojom::SuccessStatus::New();
  status_ptr->success = true;
  *status_ptr->failure_reason = "failed";

  SuccessStatus status = ToProto(status_ptr);
  EXPECT_EQ(status.success(), true);
  EXPECT_EQ(status.failure_reason(), "failed");
}

TEST(ProtoMojomConversionTest, VideoStreamParamsToProto) {
  chromeos::media_perception::mojom::VideoStreamParamsPtr params_ptr;
  VideoStreamParams params = ToProto(params_ptr);
  EXPECT_EQ(params.width_in_pixels(), 0);

  params = ToProto(CreateVideoStreamParamsPtr(1, 2, 3));
  EXPECT_EQ(params.width_in_pixels(), 1);
  EXPECT_EQ(params.height_in_pixels(), 2);
  EXPECT_EQ(params.frame_rate_in_frames_per_second(), 3);
  EXPECT_EQ(params.pixel_format(), PixelFormat::I420);
}

TEST(ProtoMojomConversionTest, VideoDeviceToProto) {
  chromeos::media_perception::mojom::VideoDevicePtr device_ptr =
      CreateVideoDevicePtr("id", "display_name", "model_id", true);

  VideoDevice device = ToProto(device_ptr);
  EXPECT_EQ(device.id(), "id");
  EXPECT_EQ(device.display_name(), "display_name");
  EXPECT_EQ(device.model_id(), "model_id");
  EXPECT_EQ(device.in_use(), true);
  EXPECT_EQ(device.configuration().width_in_pixels(), 1);
  EXPECT_EQ(device.configuration().height_in_pixels(), 2);
  EXPECT_EQ(device.configuration().frame_rate_in_frames_per_second(), 3);
  EXPECT_EQ(device.configuration().pixel_format(), PixelFormat::I420);
  EXPECT_EQ(device.supported_configurations().size(),
            kNumSupportedConfigurations);
  for (int i = 0; i < kNumSupportedConfigurations; i++) {
    EXPECT_EQ(device.supported_configurations(i).width_in_pixels(),
              i * kNumSupportedConfigurations);
  }
}

TEST(ProtoMojomConversionTest, VirtualVideoDeviceToProto) {
  chromeos::media_perception::mojom::VirtualVideoDevicePtr device_ptr =
      chromeos::media_perception::mojom::VirtualVideoDevice::New();
  device_ptr->video_device =
      CreateVideoDevicePtr("id", "display_name", "model_id", true);
  VirtualVideoDevice device = ToProto(device_ptr);
  EXPECT_EQ(device.video_device().id(), "id");
}

TEST(ProtoMojomConversionTest, AudioStreamParamsToProto) {
  chromeos::media_perception::mojom::AudioStreamParamsPtr params_ptr;
  AudioStreamParams params = ToProto(params_ptr);
  EXPECT_EQ(params.frequency_in_hz(), 0);

  params = ToProto(CreateAudioStreamParamsPtr(1, 2, 3));
  EXPECT_EQ(params.frequency_in_hz(), 1);
  EXPECT_EQ(params.num_channels(), 2);
  EXPECT_EQ(params.frame_size(), 3);
  EXPECT_EQ(params.sample_format(), SampleFormat::SND_PCM_FORMAT_S16_LE);
}

TEST(ProtoMojomConversionTest, AudioDeviceToProto) {
  chromeos::media_perception::mojom::AudioDevicePtr device_ptr =
      CreateAudioDevicePtr("id", "display_name");

  AudioDevice device = ToProto(device_ptr);
  EXPECT_EQ(device.id(), "id");
  EXPECT_EQ(device.display_name(), "display_name");
  EXPECT_EQ(device.configuration().frequency_in_hz(), 1);
  EXPECT_EQ(device.configuration().num_channels(), 2);
  EXPECT_EQ(device.supported_configurations().size(),
            kNumSupportedConfigurations);
  for (int i = 0; i < kNumSupportedConfigurations; i++) {
    EXPECT_EQ(device.supported_configurations(i).frequency_in_hz(),
              i * kNumSupportedConfigurations);
  }
}

TEST(ProtoMojomConversionTest, DeviceTemplateToProto) {
  chromeos::media_perception::mojom::DeviceTemplatePtr template_ptr =
      chromeos::media_perception::mojom::DeviceTemplate::New();
  template_ptr->template_name = "template_name";
  template_ptr->device_type =
      chromeos::media_perception::mojom::DeviceType::VIRTUAL_VIDEO;
  DeviceTemplate device_template = ToProto(template_ptr);
  EXPECT_EQ(device_template.template_name(), "template_name");
  EXPECT_EQ(device_template.device_type(), DeviceType::VIRTUAL_VIDEO);
}

TEST(ProtoMojomConversionTest, NormalizedBoundingBoxToProto) {
  chromeos::media_perception::mojom::NormalizedBoundingBoxPtr bbox_ptr =
      chromeos::media_perception::mojom::NormalizedBoundingBox::New();
  bbox_ptr->x_min = 0.1;
  bbox_ptr->y_min = 0.2;
  bbox_ptr->x_max = 0.7;
  bbox_ptr->y_max = 0.8;
  bbox_ptr->normalization_width = 10;
  bbox_ptr->normalization_height = 20;

  NormalizedBoundingBox bbox = ToProto(bbox_ptr);
  EXPECT_FLOAT_EQ(bbox.x_min(), 0.1);
  EXPECT_FLOAT_EQ(bbox.y_min(), 0.2);
  EXPECT_FLOAT_EQ(bbox.x_max(), 0.7);
  EXPECT_FLOAT_EQ(bbox.y_max(), 0.8);
  EXPECT_FLOAT_EQ(bbox.normalization_width(), 10);
  EXPECT_FLOAT_EQ(bbox.normalization_height(), 20);
}

TEST(ProtoMojomConversionTest, DistanceToProto) {
  chromeos::media_perception::mojom::DistancePtr distance_ptr =
      chromeos::media_perception::mojom::Distance::New();
  distance_ptr->units =
      chromeos::media_perception::mojom::DistanceUnits::METERS;
  distance_ptr->magnitude = 1.5;

  Distance distance = ToProto(distance_ptr);
  EXPECT_EQ(distance.units(), DistanceUnits::METERS);
  EXPECT_FLOAT_EQ(distance.magnitude(), 1.5);
}

TEST(ProtoMojomConversionTest, HotwordDetectionToProto) {
  chromeos::media_perception::mojom::HotwordDetectionPtr hotword_detection_ptr =
      chromeos::media_perception::mojom::HotwordDetection::New();
  hotword_detection_ptr->hotwords.resize(2);

  hotword_detection_ptr->hotwords[0] =
      chromeos::media_perception::mojom::Hotword::New();
  hotword_detection_ptr->hotwords[0]->type =
      chromeos::media_perception::mojom::HotwordType::HOTWORD_TYPE_UNKNOWN;
  hotword_detection_ptr->hotwords[0]->start_timestamp_ms = 100;
  hotword_detection_ptr->hotwords[0]->end_timestamp_ms = 250;

  hotword_detection_ptr->hotwords[1] =
      chromeos::media_perception::mojom::Hotword::New();
  hotword_detection_ptr->hotwords[1]->type =
      chromeos::media_perception::mojom::HotwordType::OK_GOOGLE;
  hotword_detection_ptr->hotwords[1]->start_timestamp_ms = 560;
  hotword_detection_ptr->hotwords[1]->end_timestamp_ms = 700;

  HotwordDetection hotword_detection = ToProto(hotword_detection_ptr);
  EXPECT_EQ(hotword_detection.hotwords_size(), 2);

  EXPECT_EQ(hotword_detection.hotwords(0).type(),
            HotwordType::HOTWORD_TYPE_UNKNOWN);
  EXPECT_EQ(hotword_detection.hotwords(0).start_timestamp_ms(), 100);
  EXPECT_EQ(hotword_detection.hotwords(0).end_timestamp_ms(), 250);

  EXPECT_EQ(hotword_detection.hotwords(1).type(), HotwordType::OK_GOOGLE);
  EXPECT_EQ(hotword_detection.hotwords(1).start_timestamp_ms(), 560);
  EXPECT_EQ(hotword_detection.hotwords(1).end_timestamp_ms(), 700);
}

TEST(ProtoMojomConversionTest, EntityToProto) {
  chromeos::media_perception::mojom::EntityPtr entity_ptr =
      chromeos::media_perception::mojom::Entity::New();
  entity_ptr->type = chromeos::media_perception::mojom::EntityType::FACE;
  *entity_ptr->label = "face 0";
  entity_ptr->confidence = 0.1;
  entity_ptr->depth = chromeos::media_perception::mojom::Distance::New();
  entity_ptr->depth->magnitude = 2.5;
  entity_ptr->bounding_box =
      chromeos::media_perception::mojom::NormalizedBoundingBox::New();
  entity_ptr->bounding_box->x_min = 0.6;

  Entity entity = ToProto(entity_ptr);
  EXPECT_EQ(entity.type(), EntityType::FACE);
  EXPECT_EQ(entity.label(), "face 0");
  EXPECT_FLOAT_EQ(entity.confidence(), 0.1);
  EXPECT_FLOAT_EQ(entity.depth().magnitude(), 2.5);
  EXPECT_FLOAT_EQ(entity.bounding_box().x_min(), 0.6);
}

TEST(ProtoMojomConversionTest, FramePerceptionToProto) {
  chromeos::media_perception::mojom::FramePerceptionPtr perception_ptr =
      chromeos::media_perception::mojom::FramePerception::New();
  perception_ptr->frame_id = 1;
  perception_ptr->timestamp_us = 157;
  perception_ptr->perception_types.push_back(
      chromeos::media_perception::mojom::FramePerceptionType::FACE_DETECTION);
  perception_ptr->perception_types.push_back(
      chromeos::media_perception::mojom::FramePerceptionType::PERSON_DETECTION);
  perception_ptr->perception_types.push_back(
      chromeos::media_perception::mojom::FramePerceptionType::MOTION_DETECTION);
  perception_ptr->entities.resize(4);
  perception_ptr->entities[0] =
      chromeos::media_perception::mojom::Entity::New();
  perception_ptr->entities[1] =
      chromeos::media_perception::mojom::Entity::New();
  perception_ptr->entities[2] =
      chromeos::media_perception::mojom::Entity::New();
  perception_ptr->entities[3] =
      chromeos::media_perception::mojom::Entity::New();
  perception_ptr->entities[0]->type =
      chromeos::media_perception::mojom::EntityType::FACE;
  perception_ptr->entities[1]->type =
      chromeos::media_perception::mojom::EntityType::PERSON;
  perception_ptr->entities[2]->type =
      chromeos::media_perception::mojom::EntityType::MOTION_REGION;
  perception_ptr->entities[3]->type =
      chromeos::media_perception::mojom::EntityType::LABELED_REGION;

  FramePerception perception = ToProto(perception_ptr);
  EXPECT_EQ(perception.frame_id(), 1);
  EXPECT_EQ(perception.timestamp_us(), 157);
  EXPECT_EQ(perception.perception_types_size(), 3);
  EXPECT_EQ(perception.perception_types(0),
            FramePerceptionType::FACE_DETECTION);
  EXPECT_EQ(perception.perception_types(1),
            FramePerceptionType::PERSON_DETECTION);
  EXPECT_EQ(perception.perception_types(2),
            FramePerceptionType::MOTION_DETECTION);
  EXPECT_EQ(perception.entities_size(), 4);
  EXPECT_EQ(perception.entities(0).type(), EntityType::FACE);
  EXPECT_EQ(perception.entities(1).type(), EntityType::PERSON);
  EXPECT_EQ(perception.entities(2).type(), EntityType::MOTION_REGION);
  EXPECT_EQ(perception.entities(3).type(), EntityType::LABELED_REGION);
}

TEST(ProtoMojomConversionTest, PipelineErrorToProto) {
  // Construct mojom ptr for PipelineError.
  chromeos::media_perception::mojom::PipelineErrorPtr error_ptr =
      chromeos::media_perception::mojom::PipelineError::New();
  error_ptr->error_type =
      chromeos::media_perception::mojom::PipelineErrorType::CONFIGURATION;
  *error_ptr->error_source = kMockErrorSource;
  *error_ptr->error_string = kMockErrorString;

  PipelineError error = ToProto(error_ptr);
  EXPECT_EQ(error.error_type(), PipelineErrorType::CONFIGURATION);
  EXPECT_EQ(error.error_source(), kMockErrorSource);
  EXPECT_EQ(error.error_string(), kMockErrorString);
}

TEST(ProtoMojomConversionTest, PipelineStateToProto) {
  chromeos::media_perception::mojom::PipelineStatePtr state_ptr =
      chromeos::media_perception::mojom::PipelineState::New();
  state_ptr->status =
      chromeos::media_perception::mojom::PipelineStatus::RUNNING;

  state_ptr->error = chromeos::media_perception::mojom::PipelineError::New();

  state_ptr->error->error_type =
      chromeos::media_perception::mojom::PipelineErrorType::CONFIGURATION;
  *state_ptr->error->error_source = kMockErrorSource;
  *state_ptr->error->error_string = kMockErrorString;

  *state_ptr->configuration_name = kMockConfigurationName;

  PipelineState state = ToProto(state_ptr);
  EXPECT_EQ(state.status(), PipelineStatus::RUNNING);
  EXPECT_EQ(state.configuration_name(), kMockConfigurationName);
  EXPECT_EQ(state.error().error_type(), PipelineErrorType::CONFIGURATION);
  EXPECT_EQ(state.error().error_source(), kMockErrorSource);
  EXPECT_EQ(state.error().error_string(), kMockErrorString);
}

TEST(ProtoMojomConversionTest, PresencePerceptionToProto) {
  chromeos::media_perception::mojom::PresencePerceptionPtr perception_ptr =
      chromeos::media_perception::mojom::PresencePerception::New();
  perception_ptr->timestamp_us = 100;
  perception_ptr->presence_confidence = 0.5;

  PresencePerception perception = ToProto(perception_ptr);
  EXPECT_EQ(perception.timestamp_us(), 100);
  EXPECT_FLOAT_EQ(perception.presence_confidence(), 0.5);
}

TEST(ProtoMojomConversionTest, OccupancyTriggerToProto) {
  chromeos::media_perception::mojom::OccupancyTriggerPtr occupancy_ptr =
      chromeos::media_perception::mojom::OccupancyTrigger::New();
  occupancy_ptr->trigger = true;
  occupancy_ptr->timestamp_ms = 100;

  OccupancyTrigger occupancy_trigger = ToProto(occupancy_ptr);
  EXPECT_EQ(occupancy_trigger.trigger(), true);
  EXPECT_EQ(occupancy_trigger.timestamp_ms(), 100);
}

}  // namespace
}  // namespace mri
