// 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 <string>

#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>

#include "libmems/common_types.h"
#include "libmems/iio_channel.h"
#include "libmems/iio_context_impl.h"
#include "libmems/iio_device_trigger_impl.h"

namespace {

constexpr char kAddTrigger[] = "add_trigger";

}  // namespace

namespace libmems {

base::Optional<int> IioDeviceTriggerImpl::GetIdFromString(const char* id_str) {
  size_t id_len = strlen(id_str);
  if (id_len == strlen(kIioSysfsTrigger) &&
      strncmp(id_str, kIioSysfsTrigger, id_len) == 0) {
    return -1;
  }

  return IioDevice::GetIdAfterPrefix(id_str, kTriggerIdPrefix);
}

std::string IioDeviceTriggerImpl::GetStringFromId(int id) {
  if (id == -1)
    return std::string(kIioSysfsTrigger);
  return base::StringPrintf("trigger%d", id);
}

IioDeviceTriggerImpl::IioDeviceTriggerImpl(IioContextImpl* ctx, iio_device* dev)
    : IioDevice(), context_(ctx), trigger_(dev) {
  CHECK(context_);
  CHECK(trigger_);

  log_prefix_ = base::StringPrintf("Trigger with id: %d and name: %s. ",
                                   GetId(), (GetName() ? GetName() : "null"));
}

IioContext* IioDeviceTriggerImpl::GetContext() const {
  return context_;
}

const char* IioDeviceTriggerImpl::GetName() const {
  return iio_device_get_name(trigger_);
}

int IioDeviceTriggerImpl::GetId() const {
  const char* id_str = iio_device_get_id(trigger_);

  auto id = GetIdFromString(id_str);
  DCHECK(id.has_value());
  return id.value();
}

base::FilePath IioDeviceTriggerImpl::GetPath() const {
  int id = GetId();
  std::string id_str = std::string(kIioSysfsTrigger);
  if (id >= 0)
    id_str = GetStringFromId(id);

  auto path = base::FilePath(kSysDevString).Append(id_str);
  CHECK(base::DirectoryExists(path));
  return path;
}

base::Optional<std::string> IioDeviceTriggerImpl::ReadStringAttribute(
    const std::string& name) const {
  char data[kReadAttrBufferSize] = {0};
  ssize_t len =
      iio_device_attr_read(trigger_, name.c_str(), data, sizeof(data));
  if (len < 0) {
    LOG(WARNING) << log_prefix_ << "Attempting to read string attribute "
                 << name << " failed: " << len;
    return base::nullopt;
  }
  return std::string(data, len);
}

base::Optional<int64_t> IioDeviceTriggerImpl::ReadNumberAttribute(
    const std::string& name) const {
  long long val = 0;  // NOLINT(runtime/int)
  int error = iio_device_attr_read_longlong(trigger_, name.c_str(), &val);
  if (error) {
    LOG(WARNING) << log_prefix_ << "Attempting to read number attribute "
                 << name << " failed: " << error;
    return base::nullopt;
  }
  return val;
}

base::Optional<double> IioDeviceTriggerImpl::ReadDoubleAttribute(
    const std::string& name) const {
  double val = 0;
  int error = iio_device_attr_read_double(trigger_, name.c_str(), &val);
  if (error) {
    LOG(WARNING) << log_prefix_ << "Attempting to read double attribute "
                 << name << " failed: " << error;
    return base::nullopt;
  }
  return val;
}

bool IioDeviceTriggerImpl::WriteNumberAttribute(const std::string& name,
                                                int64_t value) {
  int id = GetId();
  if ((id == -1 && name.compare(kAddTrigger) != 0) ||
      (id != -1 && name.compare(kSamplingFrequencyAttr) != 0)) {
    return false;
  }

  int error = iio_device_attr_write_longlong(trigger_, name.c_str(), value);
  if (error) {
    LOG(WARNING) << log_prefix_ << "Attempting to write number attribute "
                 << name << " failed: " << error;
    return false;
  }
  return true;
}

bool IioDeviceTriggerImpl::WriteDoubleAttribute(const std::string& name,
                                                double value) {
  int id = GetId();
  if ((id == -1 && name.compare(kAddTrigger) != 0) ||
      (id != -1 && name.compare(kSamplingFrequencyAttr) != 0)) {
    return false;
  }

  int error = iio_device_attr_write_double(trigger_, name.c_str(), value);
  if (error) {
    LOG(WARNING) << log_prefix_ << "Attempting to write double attribute "
                 << name << " failed: " << error;
    return false;
  }
  return true;
}

}  // namespace libmems
