// 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 <gtest/gtest.h>

#include <memory>
#include <utility>
#include <vector>

#include <base/bind.h>
#include <base/optional.h>
#include <base/run_loop.h>
#include <base/stl_util.h>
#include <base/test/task_environment.h>
#include <libmems/common_types.h>
#include <libmems/test_fakes.h>
#include <mojo/core/embedder/scoped_ipc_support.h>

#include "iioservice/daemon/sensor_device_fusion_gravity.h"
#include "iioservice/daemon/sensor_device_impl.h"
#include "iioservice/daemon/sensor_metrics_mock.h"
#include "iioservice/daemon/test_fakes.h"
#include "iioservice/mojo/sensor.mojom.h"

namespace iioservice {

namespace {

constexpr int32_t kFakeFusionId = 10000;

constexpr char kDeviceAttrName[] = "FakeDeviceAttr";
constexpr char kDeviceAttrValue[] = "FakeDeviceAttrValue\0\n\0";
constexpr char kParsedDeviceAttrValue[] = "FakeDeviceAttrValue";

constexpr double kMaxFrequency = 40.0;

constexpr int32_t kFakeAccelId = 1;
constexpr int32_t kFakeGyroId = 1;

class SensorDeviceFusionGravityTest : public ::testing::Test {
 protected:
  void SetUp() override {
    SensorMetricsMock::InitializeForTesting();

    ipc_support_ = std::make_unique<mojo::core::ScopedIPCSupport>(
        task_environment_.GetMainThreadTaskRunner(),
        mojo::core::ScopedIPCSupport::ShutdownPolicy::CLEAN);

    context_ = std::make_unique<libmems::fakes::FakeIioContext>();

    auto device = std::make_unique<libmems::fakes::FakeIioDevice>(
        nullptr, fakes::kAccelDeviceName, fakes::kAccelDeviceId);

    EXPECT_TRUE(
        device->WriteStringAttribute(libmems::kSamplingFrequencyAvailable,
                                     fakes::kFakeSamplingFrequencyAvailable));
    for (int i = 0; i < base::size(libmems::fakes::kFakeAccelChns); ++i) {
      auto chn = std::make_unique<libmems::fakes::FakeIioChannel>(
          libmems::fakes::kFakeAccelChns[i], true);
      device->AddChannel(std::move(chn));
    }
    EXPECT_TRUE(
        device->WriteStringAttribute(kDeviceAttrName, kDeviceAttrValue));

    device_ = device.get();
    context_->AddDevice(std::move(device));

    sensor_device_ = SensorDeviceImpl::Create(
        task_environment_.GetMainThreadTaskRunner(), context_.get());

    sensor_device_fusion_ = SensorDeviceFusionGravity::Create(
        kFakeFusionId, Location::kBase,
        task_environment_.GetMainThreadTaskRunner(),
        base::BindRepeating(&SensorDeviceImpl::AddReceiver,
                            base::Unretained(sensor_device_.get())),
        kMaxFrequency, kFakeAccelId, kFakeGyroId);
    sensor_device_fusion_gravity_ =
        static_cast<SensorDeviceFusionGravity*>(sensor_device_fusion_.get());

    sensor_device_fusion_->AddReceiver(remote_.BindNewPipeAndPassReceiver());
    remote_.set_disconnect_handler(
        base::BindOnce(&SensorDeviceFusionGravityTest::OnSensorDeviceDisconnect,
                       base::Unretained(this)));
  }

  void TearDown() override {
    sensor_device_.reset();
    sensor_device_fusion_.reset();
    remote_.reset();
    SensorMetrics::Shutdown();
  }

  void OnSensorDeviceDisconnect() { remote_.reset(); }

  base::test::SingleThreadTaskEnvironment task_environment_{
      base::test::TaskEnvironment::TimeSource::MOCK_TIME,
      base::test::TaskEnvironment::MainThreadType::IO};

  std::unique_ptr<mojo::core::ScopedIPCSupport> ipc_support_;

  std::unique_ptr<libmems::fakes::FakeIioContext> context_;
  libmems::fakes::FakeIioDevice* device_;

  SensorDeviceImpl::ScopedSensorDeviceImpl sensor_device_ = {
      nullptr, SensorDeviceImpl::SensorDeviceImplDeleter};

  SensorDeviceFusion::ScopedSensorDeviceFusion sensor_device_fusion_ = {
      nullptr, SensorDeviceFusion::SensorDeviceFusionDeleter};
  SensorDeviceFusionGravity* sensor_device_fusion_gravity_;

  mojo::Remote<cros::mojom::SensorDevice> remote_;
};

// Despite the lack of iio gyroscope, and |sensor_device_fusion_| will be
// invalidated, attributes should be successfully retrieved.
TEST_F(SensorDeviceFusionGravityTest, GetAttributes) {
  base::RunLoop loop;

  remote_->GetAttributes(
      {kDeviceAttrName, cros::mojom::kSamplingFrequencyAvailable,
       cros::mojom::kDeviceName},
      base::BindOnce(
          [](base::RepeatingClosure closure,
             const std::vector<base::Optional<std::string>>& values) {
            EXPECT_EQ(values.size(), 3u);
            EXPECT_TRUE(values[0].has_value());
            EXPECT_EQ(values[0].value().compare(kParsedDeviceAttrValue), 0);
            EXPECT_TRUE(values[1].has_value());
            EXPECT_EQ(values[1].value(),
                      GetSamplingFrequencyAvailable(
                          SensorDeviceFusionGravity::kAccelMinFrequency,
                          kMaxFrequency));
            EXPECT_TRUE(values[2].has_value());
            EXPECT_EQ(values[2].value(), SensorDeviceFusionGravity::kName);
            closure.Run();
          },
          loop.QuitClosure()));
  loop.Run();
}

TEST_F(SensorDeviceFusionGravityTest, GetChannelsAttributes) {
  base::RunLoop loop;

  std::vector<int32_t> indices;
  size_t size = GetGravityChannels().size();
  for (size_t i = 0; i < size; ++i)
    indices.push_back(i);

  remote_->GetChannelsAttributes(
      indices, {cros::mojom::kScale},
      base::BindOnce(
          [](base::RepeatingClosure closure, size_t size,
             const std::vector<base::Optional<std::string>>& values) {
            EXPECT_EQ(values.size(), size);
            // Gravity device channels' attributes are not provided for now.
            for (size_t i = 0; i < size; ++i)
              EXPECT_FALSE(values[i].has_value());

            closure.Run();
          },
          loop.QuitClosure(), size));
  loop.Run();
}

}  // namespace

}  // namespace iioservice
