// 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 "libmems/test_fakes.h"

#include <sys/eventfd.h>

#include <base/check.h>
#include <base/check_op.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include "base/posix/eintr_wrapper.h"
#include <base/stl_util.h>

#include "libmems/common_types.h"

namespace libmems {
namespace fakes {

FakeIioChannel::FakeIioChannel(const std::string& id, bool enabled)
    : id_(id), enabled_(enabled) {}

void FakeIioChannel::SetEnabled(bool en) {
  enabled_ = en;
}

bool FakeIioChannel::SetScanElementsEnabled(bool en) {
  scan_elements_enabled_ = en;
  return true;
}

template <typename T>
base::Optional<T> FakeReadAttributes(const std::string& name,
                                     std::map<std::string, T> attributes) {
  auto k = attributes.find(name);
  if (k == attributes.end())
    return base::nullopt;
  return k->second;
}

base::Optional<std::string> FakeIioChannel::ReadStringAttribute(
    const std::string& name) const {
  return FakeReadAttributes<>(name, text_attributes_);
}
base::Optional<int64_t> FakeIioChannel::ReadNumberAttribute(
    const std::string& name) const {
  return FakeReadAttributes<>(name, numeric_attributes_);
}
base::Optional<double> FakeIioChannel::ReadDoubleAttribute(
    const std::string& name) const {
  return FakeReadAttributes<>(name, double_attributes_);
}

bool FakeIioChannel::WriteStringAttribute(const std::string& name,
                                          const std::string& value) {
  text_attributes_[name] = value;
  return true;
}
bool FakeIioChannel::WriteNumberAttribute(const std::string& name,
                                          int64_t value) {
  numeric_attributes_[name] = value;
  return true;
}
bool FakeIioChannel::WriteDoubleAttribute(const std::string& name,
                                          double value) {
  double_attributes_[name] = value;
  return true;
}

base::Optional<int64_t> FakeIioChannel::GetData(int index) {
  if (!enabled_ || index < 0 || index >= base::size(kFakeAccelSamples))
    return base::nullopt;

  auto raw = ReadNumberAttribute(kRawAttr);
  if (raw.has_value())
    return raw;

  for (int i = 0; i < base::size(kFakeAccelChns); ++i) {
    if (id_.compare(kFakeAccelChns[i]) == 0)
      return kFakeAccelSamples[index][i];
  }

  return base::nullopt;
}

FakeIioDevice::FakeIioDevice(FakeIioContext* ctx,
                             const std::string& name,
                             int id)
    : IioDevice(), context_(ctx), name_(name), id_(id) {}

base::FilePath FakeIioDevice::GetPath() const {
  if (!path_.empty())
    return path_;

  std::string id_str(kDeviceIdPrefix);
  id_str.append(std::to_string(GetId()));
  return base::FilePath(kSysDevString).Append(id_str);
}

base::Optional<std::string> FakeIioDevice::ReadStringAttribute(
    const std::string& name) const {
  if (name.compare(kDeviceName) == 0)
    return name_;
  return FakeReadAttributes<>(name, text_attributes_);
}
base::Optional<int64_t> FakeIioDevice::ReadNumberAttribute(
    const std::string& name) const {
  return FakeReadAttributes<>(name, numeric_attributes_);
}
base::Optional<double> FakeIioDevice::ReadDoubleAttribute(
    const std::string& name) const {
  return FakeReadAttributes<>(name, double_attributes_);
}

bool FakeIioDevice::WriteStringAttribute(const std::string& name,
                                         const std::string& value) {
  text_attributes_[name] = value;
  return true;
}
bool FakeIioDevice::WriteNumberAttribute(const std::string& name,
                                         int64_t value) {
  numeric_attributes_[name] = value;
  return true;
}
bool FakeIioDevice::WriteDoubleAttribute(const std::string& name,
                                         double value) {
  double_attributes_[name] = value;
  return true;
}

bool FakeIioDevice::SetTrigger(IioDevice* trigger) {
  trigger_ = trigger;
  return true;
}

bool FakeIioDevice::EnableBuffer(size_t n) {
  buffer_length_ = n;
  buffer_enabled_ = true;
  return true;
}
bool FakeIioDevice::DisableBuffer() {
  buffer_enabled_ = false;
  return true;
}
bool FakeIioDevice::IsBufferEnabled(size_t* n) const {
  if (n && buffer_enabled_)
    *n = buffer_length_;
  return buffer_enabled_;
}

bool FakeIioDevice::CreateBuffer() {
  if (disabled_fd_ || sample_fd_.is_valid())
    return false;

  int fd = eventfd(0, 0);
  CHECK_GE(fd, 0);
  sample_fd_.reset(fd);

  if (sample_index_ >= base::size(kFakeAccelSamples) || is_paused_)
    return true;

  if (!WriteByte()) {
    ClosePipe();
    return false;
  }

  return true;
}

base::Optional<int32_t> FakeIioDevice::GetBufferFd() {
  if (disabled_fd_ || !sample_fd_.is_valid())
    return base::nullopt;

  return sample_fd_.get();
}

base::Optional<IioDevice::IioSample> FakeIioDevice::ReadSample() {
  if (is_paused_ || disabled_fd_ || !sample_fd_.is_valid())
    return base::nullopt;

  if (!failed_read_queue_.empty()) {
    CHECK_GE(failed_read_queue_.top(), sample_index_);
    if (failed_read_queue_.top() == sample_index_) {
      failed_read_queue_.pop();
      return base::nullopt;
    }
  }

  if (!ReadByte())
    return base::nullopt;

  base::Optional<double> freq_opt = ReadDoubleAttribute(kSamplingFrequencyAttr);
  if (!freq_opt.has_value()) {
    LOG(ERROR) << "sampling_frequency not set";
    return base::nullopt;
  }
  double frequency = freq_opt.value();
  if (frequency <= 0.0) {
    LOG(ERROR) << "Invalid frequency: " << frequency;
    return base::nullopt;
  }

  IioDevice::IioSample sample;
  auto channels = GetAllChannels();
  for (int32_t i = 0; i < channels.size(); ++i) {
    FakeIioChannel* chn = dynamic_cast<FakeIioChannel*>(channels[i]);
    auto value = chn->GetData(sample_index_);
    if (!value.has_value()) {
      LOG(ERROR) << "Channel: " << channels_[i].chn_id << " has no sample";
      return base::nullopt;
    }

    sample[i] = value.value();
  }

  sample_index_ += 1;

  if (sample_index_ < base::size(kFakeAccelSamples)) {
    if (pause_index_.has_value() && sample_index_ == pause_index_.value())
      SetPause();
    else if (!WriteByte())
      return base::nullopt;
  }

  return sample;
}

void FakeIioDevice::FreeBuffer() {
  ClosePipe();
}

void FakeIioDevice::DisableFd() {
  disabled_fd_ = true;
  if (readable_fd_)
    CHECK(ReadByte());
}

void FakeIioDevice::AddFailedReadAtKthSample(int k) {
  CHECK_GE(k, sample_index_);

  failed_read_queue_.push(k);
}

void FakeIioDevice::SetPauseCallbackAtKthSamples(
    int k, base::OnceCallback<void()> callback) {
  CHECK_GE(k, sample_index_);
  CHECK_LE(k, base::size(kFakeAccelSamples));
  CHECK(!pause_index_.has_value());  // pause callback hasn't been set

  pause_index_ = k;
  pause_callback_ = std::move(callback);

  if (pause_index_.value() != sample_index_)
    return;

  SetPause();
}

void FakeIioDevice::ResumeReadingSamples() {
  CHECK(is_paused_);

  is_paused_ = false;
  if (sample_fd_.is_valid() && !readable_fd_)
    CHECK(WriteByte());
}

bool FakeIioDevice::WriteByte() {
  if (!sample_fd_.is_valid())
    return false;

  CHECK(!readable_fd_);
  uint64_t val = 1;
  CHECK_EQ(write(sample_fd_.get(), &val, sizeof(uint64_t)), sizeof(uint64_t));
  readable_fd_ = true;

  return true;
}

bool FakeIioDevice::ReadByte() {
  if (!sample_fd_.is_valid())
    return false;

  CHECK(readable_fd_);
  int64_t val = 1;
  CHECK_EQ(read(sample_fd_.get(), &val, sizeof(uint64_t)), sizeof(uint64_t));
  readable_fd_ = false;

  return true;
}

void FakeIioDevice::ClosePipe() {
  sample_fd_.reset();
}

void FakeIioDevice::SetPause() {
  is_paused_ = true;
  pause_index_.reset();
  std::move(pause_callback_).Run();
  if (readable_fd_)
    CHECK(ReadByte());
}

void FakeIioContext::AddDevice(std::unique_ptr<FakeIioDevice> device) {
  CHECK(device.get());
  devices_.emplace(device->GetId(), std::move(device));
}

void FakeIioContext::AddTrigger(std::unique_ptr<FakeIioDevice> trigger) {
  CHECK(trigger.get());
  triggers_.emplace(trigger->GetId(), std::move(trigger));
}

std::vector<IioDevice*> FakeIioContext::GetDevicesByName(
    const std::string& name) {
  return GetFakeByName(name, devices_);
}

IioDevice* FakeIioContext::GetDeviceById(int id) {
  return GetFakeById(id, devices_);
}

std::vector<IioDevice*> FakeIioContext::GetAllDevices() {
  return GetFakeAll(devices_);
}

std::vector<IioDevice*> FakeIioContext::GetTriggersByName(
    const std::string& name) {
  return GetFakeByName(name, triggers_);
}

IioDevice* FakeIioContext::GetTriggerById(int id) {
  return GetFakeById(id, triggers_);
}

std::vector<IioDevice*> FakeIioContext::GetAllTriggers() {
  return GetFakeAll(triggers_);
}

IioDevice* FakeIioContext::GetFakeById(
    int id, const std::map<int, std::unique_ptr<FakeIioDevice>>& devices_map) {
  auto k = devices_map.find(id);
  return (k == devices_map.end()) ? nullptr : k->second.get();
}

std::vector<IioDevice*> FakeIioContext::GetFakeByName(
    const std::string& name,
    const std::map<int, std::unique_ptr<FakeIioDevice>>& devices_map) {
  std::vector<IioDevice*> devices;
  for (auto const& it : devices_map) {
    if (name.compare(it.second->GetName()) == 0)
      devices.push_back(it.second.get());
  }

  return devices;
}

std::vector<IioDevice*> FakeIioContext::GetFakeAll(
    const std::map<int, std::unique_ptr<FakeIioDevice>>& devices_map) {
  std::vector<IioDevice*> devices;
  for (auto const& it : devices_map)
    devices.push_back(it.second.get());

  return devices;
}

}  // namespace fakes
}  // namespace libmems
