// Copyright 2019 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 <base/files/file_util.h>

#include <gtest/gtest.h>

#include <libmems/common_types.h>
#include <libmems/iio_context.h>
#include <libmems/iio_device.h>
#include <libmems/iio_device_impl.h>
#include <libmems/test_fakes.h>
#include "mems_setup/configuration.h"
#include "mems_setup/delegate.h"
#include "mems_setup/sensor_location.h"
#include "mems_setup/test_fakes.h"
#include "mems_setup/test_helper.h"

using libmems::fakes::FakeIioChannel;
using libmems::fakes::FakeIioDevice;
using mems_setup::testing::SensorTestBase;

namespace mems_setup {

namespace {

static gid_t kChronosGroupId = 666;
static gid_t kIioserviceGroupId = 777;
static gid_t kPowerGroupId = 999;

constexpr int kDeviceId = 1;
constexpr char kTriggerString[] = "trigger";
constexpr char kHwfifoTimeoutString[] = "buffer/hwfifo_timeout";
constexpr char kFlushString[] = "flush";

#if USE_IIOSERVICE
constexpr char kDevString[] = "/dev/";
#endif  // USE_IIOSERVICE

class AccelerometerTest : public SensorTestBase {
 public:
  AccelerometerTest() : SensorTestBase("cros-ec-accel", kDeviceId) {
    mock_delegate_->AddGroup("chronos", kChronosGroupId);
    mock_delegate_->AddGroup(Configuration::GetGroupNameForSysfs(),
                             kIioserviceGroupId);

    std::string dev_name = libmems::IioDeviceImpl::GetStringFromId(kDeviceId);
    // /sys/bus/iio/devices/iio:device1
    base::FilePath sys_dev_path = mock_device_->GetPath();

    // Create the file to set the trigger in |AddSysfsTrigger|.
    mock_delegate_->CreateFile(sys_dev_path.Append(kTriggerString));

    // Create the files to set permissions and ownership for test.
    mock_delegate_->CreateFile(sys_dev_path.Append(kHwfifoTimeoutString));
    mock_delegate_->CreateFile(sys_dev_path.Append(kFlushString));
  }

  void CheckPermissionsAndOwnershipForFile(const base::FilePath& path,
                                           int permission) {
    uid_t user;
    gid_t group;

    EXPECT_TRUE(mock_delegate_->GetOwnership(path, &user, &group));
    EXPECT_EQ(group, kIioserviceGroupId);
    EXPECT_EQ(permission, mock_delegate_->GetPermissions(path));
  }
};

TEST_F(AccelerometerTest, CheckPermissionsAndOwnership) {
  SetSingleSensor(kBaseSensorLocation);
  ConfigureVpd({{"in_accel_x_base_calibbias", "100"}});

  EXPECT_TRUE(GetConfiguration()->Configure());

  std::string dev_name = libmems::IioDeviceImpl::GetStringFromId(kDeviceId);

  // /sys/bus/iio/devices/iio:device1
  base::FilePath sys_dev_path = mock_device_->GetPath();

  CheckPermissionsAndOwnershipForFile(sys_dev_path.Append(kHwfifoTimeoutString),
                                      base::FILE_PERMISSION_WRITE_BY_GROUP |
                                          base::FILE_PERMISSION_READ_BY_GROUP);
  CheckPermissionsAndOwnershipForFile(sys_dev_path.Append(kFlushString),
                                      base::FILE_PERMISSION_WRITE_BY_GROUP);

#if USE_IIOSERVICE
  // /dev/iio:deviceX
  base::FilePath dev_path = base::FilePath(kDevString).Append(dev_name.c_str());

  CheckPermissionsAndOwnershipForFile(dev_path,
                                      base::FILE_PERMISSION_WRITE_BY_GROUP |
                                          base::FILE_PERMISSION_READ_BY_GROUP);
#endif  // USE_IIOSERVICE
}

#if USE_IIOSERVICE
TEST_F(AccelerometerTest, FrequencyReset) {
  SetSingleSensor(kBaseSensorLocation);
  ConfigureVpd({{"in_accel_x_base_calibbias", "100"}});

  EXPECT_TRUE(GetConfiguration()->Configure());

  auto frequency_opt =
      mock_device_->ReadDoubleAttribute(libmems::kSamplingFrequencyAttr);
  EXPECT_TRUE(frequency_opt.has_value());
  EXPECT_EQ(frequency_opt.value(), 0.0);
}
#endif  // USE_IIOSERVICE

TEST_F(AccelerometerTest, CheckClock) {
  SetSingleSensor(kBaseSensorLocation);
  ConfigureVpd({{"in_accel_x_base_calibbias", "100"}});

  EXPECT_TRUE(GetConfiguration()->Configure());
  auto attr_opt = mock_device_->ReadStringAttribute("current_timestamp_clock");
  EXPECT_TRUE(attr_opt.has_value());
  EXPECT_EQ(attr_opt.value(), "boottime");
}

TEST_F(AccelerometerTest, MissingVpd) {
  SetSingleSensor(kBaseSensorLocation);
  ConfigureVpd({{"in_accel_x_base_calibbias", "100"}});

  EXPECT_TRUE(GetConfiguration()->Configure());

  EXPECT_TRUE(mock_device_->GetChannel("accel_x")
                  ->ReadNumberAttribute("calibbias")
                  .has_value());
  EXPECT_EQ(100, mock_device_->GetChannel("accel_x")
                     ->ReadNumberAttribute("calibbias")
                     .value());
  EXPECT_FALSE(mock_device_->GetChannel("accel_y")
                   ->ReadNumberAttribute("calibbias")
                   .has_value());
  EXPECT_FALSE(mock_device_->GetChannel("accel_z")
                   ->ReadNumberAttribute("calibbias")
                   .has_value());
}

TEST_F(AccelerometerTest, NotNumericVpd) {
  SetSingleSensor(kBaseSensorLocation);
  ConfigureVpd({{"in_accel_x_base_calibbias", "blah"},
                {"in_accel_y_base_calibbias", "100"}});

  EXPECT_TRUE(GetConfiguration()->Configure());

  EXPECT_FALSE(mock_device_->GetChannel("accel_x")
                   ->ReadNumberAttribute("calibbias")
                   .has_value());
  EXPECT_TRUE(mock_device_->GetChannel("accel_y")
                  ->ReadNumberAttribute("calibbias")
                  .has_value());
  EXPECT_EQ(100, mock_device_->GetChannel("accel_y")
                     ->ReadNumberAttribute("calibbias")
                     .value());
  EXPECT_FALSE(mock_device_->GetChannel("accel_z")
                   ->ReadNumberAttribute("calibbias")
                   .has_value());
}

TEST_F(AccelerometerTest, VpdOutOfRange) {
  SetSingleSensor(kBaseSensorLocation);
  ConfigureVpd({{"in_accel_x_base_calibbias", "104"},  // just above .100g.
                {"in_accel_y_base_calibbias", "100"},
                {"in_accel_z_base_calibbias", "85"}});

  EXPECT_TRUE(GetConfiguration()->Configure());

  EXPECT_FALSE(mock_device_->GetChannel("accel_x")
                   ->ReadNumberAttribute("calibbias")
                   .has_value());
  EXPECT_FALSE(mock_device_->GetChannel("accel_y")
                   ->ReadNumberAttribute("calibbias")
                   .has_value());
  EXPECT_FALSE(mock_device_->GetChannel("accel_z")
                   ->ReadNumberAttribute("calibbias")
                   .has_value());
}

TEST_F(AccelerometerTest, CalibscaleData) {
  SetSingleSensor(kBaseSensorLocation);
  ConfigureVpd({{"in_accel_x_base_calibscale", "5"},
                {"in_accel_y_base_calibscale", "6"},
                {"in_accel_z_base_calibscale", "7"}});

  EXPECT_TRUE(GetConfiguration()->Configure());

  EXPECT_TRUE(mock_device_->GetChannel("accel_x")
                  ->ReadNumberAttribute("calibscale")
                  .has_value());
  EXPECT_TRUE(mock_device_->GetChannel("accel_y")
                  ->ReadNumberAttribute("calibscale")
                  .has_value());
  EXPECT_TRUE(mock_device_->GetChannel("accel_z")
                  ->ReadNumberAttribute("calibscale")
                  .has_value());

  EXPECT_EQ(5, mock_device_->GetChannel("accel_x")
                   ->ReadNumberAttribute("calibscale")
                   .value());
  EXPECT_EQ(6, mock_device_->GetChannel("accel_y")
                   ->ReadNumberAttribute("calibscale")
                   .value());
  EXPECT_EQ(7, mock_device_->GetChannel("accel_z")
                   ->ReadNumberAttribute("calibscale")
                   .value());
}

TEST_F(AccelerometerTest, CalibscaleZeroData) {
  SetSingleSensor(kBaseSensorLocation);
  ConfigureVpd({{"in_accel_x_base_calibscale", "5"},
                {"in_accel_y_base_calibscale", "6"},
                {"in_accel_z_base_calibscale", "0"}});

  EXPECT_TRUE(GetConfiguration()->Configure());

  EXPECT_TRUE(mock_device_->GetChannel("accel_x")
                  ->ReadNumberAttribute("calibscale")
                  .has_value());
  EXPECT_TRUE(mock_device_->GetChannel("accel_y")
                  ->ReadNumberAttribute("calibscale")
                  .has_value());
  EXPECT_TRUE(mock_device_->GetChannel("accel_z")
                  ->ReadNumberAttribute("calibscale")
                  .has_value());

  EXPECT_EQ(5, mock_device_->GetChannel("accel_x")
                   ->ReadNumberAttribute("calibscale")
                   .value());
  EXPECT_EQ(6, mock_device_->GetChannel("accel_y")
                   ->ReadNumberAttribute("calibscale")
                   .value());
  EXPECT_EQ(0, mock_device_->GetChannel("accel_z")
                   ->ReadNumberAttribute("calibscale")
                   .value());
}

TEST_F(AccelerometerTest, NotLoadingTriggerModule) {
  SetSingleSensor(kBaseSensorLocation);
  ConfigureVpd({{"in_accel_x_base_calibbias", "50"},
                {"in_accel_y_base_calibbias", "100"},
                {"in_accel_z_base_calibbias", "85"}});

  EXPECT_TRUE(GetConfiguration()->Configure());

  EXPECT_EQ(0, mock_delegate_->GetNumModulesProbed());
}

TEST_F(AccelerometerTest, MultipleSensorDevice) {
  SetSharedSensor();
  ConfigureVpd({{"in_accel_x_base_calibbias", "50"},
                {"in_accel_y_base_calibbias", "100"},
                {"in_accel_z_base_calibbias", "85"},
                {"in_accel_y_lid_calibbias", "27"}});

  EXPECT_TRUE(GetConfiguration()->Configure());

  EXPECT_TRUE(mock_device_->GetChannel("accel_x_base")
                  ->ReadNumberAttribute("calibbias")
                  .has_value());
  EXPECT_TRUE(mock_device_->GetChannel("accel_y_base")
                  ->ReadNumberAttribute("calibbias")
                  .has_value());
  EXPECT_TRUE(mock_device_->GetChannel("accel_z_base")
                  ->ReadNumberAttribute("calibbias")
                  .has_value());

  EXPECT_EQ(50, mock_device_->GetChannel("accel_x_base")
                    ->ReadNumberAttribute("calibbias")
                    .value());
  EXPECT_EQ(100, mock_device_->GetChannel("accel_y_base")
                     ->ReadNumberAttribute("calibbias")
                     .value());
  EXPECT_EQ(85, mock_device_->GetChannel("accel_z_base")
                    ->ReadNumberAttribute("calibbias")
                    .value());

  EXPECT_FALSE(mock_device_->GetChannel("accel_x_lid")
                   ->ReadNumberAttribute("calibbias")
                   .has_value());
  EXPECT_TRUE(mock_device_->GetChannel("accel_y_lid")
                  ->ReadNumberAttribute("calibbias")
                  .has_value());
  EXPECT_EQ(27, mock_device_->GetChannel("accel_y_lid")
                    ->ReadNumberAttribute("calibbias")
                    .value());
  EXPECT_FALSE(mock_device_->GetChannel("accel_z_lid")
                   ->ReadNumberAttribute("calibbias")
                   .has_value());
}

TEST_F(AccelerometerTest, TriggerPermissions) {
  SetSingleSensor(kLidSensorLocation);
  EXPECT_TRUE(GetConfiguration()->Configure());

  base::FilePath trigger_now = mock_trigger1_->GetPath().Append("trigger_now");
  EXPECT_NE(0, mock_delegate_->GetPermissions(trigger_now) &
                   base::FILE_PERMISSION_WRITE_BY_GROUP);
  gid_t gid = 0;
  mock_delegate_->GetOwnership(trigger_now, nullptr, &gid);
  EXPECT_EQ(kChronosGroupId, gid);
}

#if !USE_IIOSERVICE
TEST_F(AccelerometerTest, SingleSensorEnableChannels) {
  SetSingleSensor(kLidSensorLocation);
  EXPECT_TRUE(GetConfiguration()->Configure());

  for (auto channel : mock_device_->GetAllChannels()) {
    if (strcmp(channel->GetId(), "calibration") == 0)
      continue;
    EXPECT_EQ(static_cast<FakeIioChannel*>(channel)->IsScanElementsEnabled(),
              0 != strcmp(channel->GetId(), "timestamp"));
  }
}

TEST_F(AccelerometerTest, MultipleSensorEnableChannels) {
  SetSharedSensor();
  EXPECT_TRUE(GetConfiguration()->Configure());

  for (auto channel : mock_device_->GetAllChannels()) {
    if (strcmp(channel->GetId(), "calibration") == 0)
      continue;
    EXPECT_EQ(static_cast<FakeIioChannel*>(channel)->IsScanElementsEnabled(),
              0 != strcmp(channel->GetId(), "timestamp"));
  }
}

TEST_F(AccelerometerTest, BufferEnabled) {
  SetSingleSensor(kLidSensorLocation);
  EXPECT_FALSE(mock_device_->IsBufferEnabled());

  EXPECT_TRUE(GetConfiguration()->Configure());

  size_t accel_buffer_len = 0;
  EXPECT_TRUE(mock_device_->IsBufferEnabled(&accel_buffer_len));
  EXPECT_EQ(1, accel_buffer_len);
}
#endif

TEST_F(AccelerometerTest, SingleSensorKbWakeAnglePermissions) {
  base::FilePath kb_path("/sys/class/chromeos/cros_ec/kb_wake_angle");

  SetSingleSensor(kLidSensorLocation);
  mock_delegate_->CreateFile(kb_path);
  mock_delegate_->AddGroup("power", kPowerGroupId);
  EXPECT_TRUE(GetConfiguration()->Configure());

  EXPECT_NE(0, mock_delegate_->GetPermissions(kb_path) &
                   base::FILE_PERMISSION_WRITE_BY_GROUP);
  gid_t gid = 0;
  mock_delegate_->GetOwnership(kb_path, nullptr, &gid);
  EXPECT_EQ(kPowerGroupId, gid);
}

TEST_F(AccelerometerTest, OkWithSysfstrigDefined) {
  SetSingleSensor(kLidSensorLocation);

  mock_sysfs_trigger_->AddMockTrigger();

  EXPECT_TRUE(GetConfiguration()->Configure());
}

TEST_F(AccelerometerTest, SetRangeNoGyroLid) {
  SetSingleSensor(kLidSensorLocation);
  EXPECT_TRUE(GetConfiguration()->Configure());
  EXPECT_EQ(4, mock_device_->ReadNumberAttribute("scale").value());
}

TEST_F(AccelerometerTest, SetRangeNoGyroLidOld) {
  SetSharedSensor();
  SetSingleSensor(kBaseSensorLocation);
  EXPECT_TRUE(GetConfiguration()->Configure());
  EXPECT_NE(4, mock_device_->ReadNumberAttribute("scale").value_or(0));
}

TEST_F(AccelerometerTest, SetRangeGyroBaseBase) {
  auto mock_gyro =
      std::make_unique<FakeIioDevice>(mock_context_.get(), "cros-ec-gyro", 2);
  mock_gyro->WriteStringAttribute("location", kBaseSensorLocation);
  mock_context_->AddDevice(std::move(mock_gyro));

  SetSingleSensor(kBaseSensorLocation);
  EXPECT_TRUE(GetConfiguration()->Configure());
  EXPECT_EQ(4, mock_device_->ReadNumberAttribute("scale").value());
}

TEST_F(AccelerometerTest, SetRangeGyroBaseLid) {
  auto mock_gyro =
      std::make_unique<FakeIioDevice>(mock_context_.get(), "cros-ec-gyro", 2);
  mock_gyro->WriteStringAttribute("location", kBaseSensorLocation);
  mock_context_->AddDevice(std::move(mock_gyro));

  SetSingleSensor(kLidSensorLocation);
  EXPECT_TRUE(GetConfiguration()->Configure());
  EXPECT_EQ(2, mock_device_->ReadNumberAttribute("scale").value());
}

TEST_F(AccelerometerTest, SetRangeMultipleGyroLid) {
  auto mock_gyro1 =
      std::make_unique<FakeIioDevice>(mock_context_.get(), "cros-ec-gyro", 2);
  mock_gyro1->WriteStringAttribute("location", kBaseSensorLocation);
  mock_context_->AddDevice(std::move(mock_gyro1));

  auto mock_gyro2 =
      std::make_unique<FakeIioDevice>(mock_context_.get(), "cros-ec-gyro", 3);
  mock_gyro2->WriteStringAttribute("location", kLidSensorLocation);
  mock_context_->AddDevice(std::move(mock_gyro2));

  SetSingleSensor(kLidSensorLocation);
  EXPECT_TRUE(GetConfiguration()->Configure());
  EXPECT_EQ(4, mock_device_->ReadNumberAttribute("scale").value());
}

TEST_F(AccelerometerTest, SetRangeMultipleGyroBase) {
  auto mock_gyro1 =
      std::make_unique<FakeIioDevice>(mock_context_.get(), "cros-ec-gyro", 2);
  mock_gyro1->WriteStringAttribute("location", kBaseSensorLocation);
  mock_context_->AddDevice(std::move(mock_gyro1));

  auto mock_gyro2 =
      std::make_unique<FakeIioDevice>(mock_context_.get(), "cros-ec-gyro", 3);
  mock_gyro2->WriteStringAttribute("location", kLidSensorLocation);
  mock_context_->AddDevice(std::move(mock_gyro2));

  SetSingleSensor(kBaseSensorLocation);
  EXPECT_TRUE(GetConfiguration()->Configure());
  EXPECT_EQ(2, mock_device_->ReadNumberAttribute("scale").value());
}

}  // namespace

}  // namespace mems_setup
