// 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 "iioservice/daemon/common_types.h"

#include <optional>
#include <utility>

#include <base/files/file_util.h>
#include <base/notreached.h>
#include <base/strings/stringprintf.h>
#include <libmems/common_types.h>

namespace iioservice {

namespace {

bool IioDeviceOnDut(libmems::IioDevice* const iio_device) {
  auto path_opt = GetAbsoluteSysPath(iio_device);
  if (!path_opt.has_value())
    return false;

  base::FilePath path = path_opt.value();
  while (!path.empty() && path.DirName() != path) {
    base::FilePath sym_driver;
    if (base::ReadSymbolicLink(path.Append("driver"), &sym_driver) &&
        sym_driver.value().find("ish-hid") != std::string::npos) {
      return true;
    }

    path = path.DirName();
  }

  return false;
}

}  // namespace

std::optional<base::FilePath> GetAbsoluteSysPath(
    libmems::IioDevice* const iio_device) {
  base::FilePath iio_path(iio_device->GetPath());
  base::FilePath sys_path;
  if (base::ReadSymbolicLink(iio_path, &sys_path)) {
    if (sys_path.IsAbsolute()) {
      return sys_path;
    } else {
      base::FilePath result = iio_path.DirName();
      result = result.Append(sys_path);

      return base::MakeAbsoluteFilePath(result);
    }
  }

  return std::nullopt;
}

DeviceData::DeviceData(libmems::IioDevice* const iio_device,
                       std::set<cros::mojom::DeviceType> types)
    : iio_device(iio_device),
      types(std::move(types)),
      on_dut(IioDeviceOnDut(iio_device)) {}

ClientData::ClientData(const mojo::ReceiverId id, DeviceData* device_data)
    : id(id), device_data(device_data) {}

bool ClientData::IsSampleActive() const {
  return frequency >= libmems::kFrequencyEpsilon &&
         !enabled_chn_indices.empty();
}

bool ClientData::IsEventActive() const {
  return !enabled_event_indices.empty();
}

std::vector<std::string> GetGravityChannels() {
  std::vector<std::string> channel_ids;
  for (char axis : kChannelAxes) {
    channel_ids.push_back(
        base::StringPrintf(kChannelFormat, cros::mojom::kGravityChannel, axis));
  }
  channel_ids.push_back(cros::mojom::kTimestampChannel);

  return channel_ids;
}

std::string GetSamplingFrequencyAvailable(double min_frequency,
                                          double max_frequency) {
  return base::StringPrintf(kSamplingFrequencyAvailableFormat, min_frequency,
                            max_frequency);
}

std::optional<std::string> DeviceTypeToString(cros::mojom::DeviceType type) {
  switch (type) {
    case cros::mojom::DeviceType::ACCEL:
      return libmems::kAccelName;

    case cros::mojom::DeviceType::ANGLVEL:
      return libmems::kGyroName;

    case cros::mojom::DeviceType::LIGHT:
      return libmems::kLightName;

    case cros::mojom::DeviceType::COUNT:
      return libmems::kSyncName;

    case cros::mojom::DeviceType::MAGN:
      return libmems::kMagnName;

    case cros::mojom::DeviceType::ANGL:
      return libmems::kLidAngleName;

    case cros::mojom::DeviceType::BARO:
      return libmems::kBaroName;

    case cros::mojom::DeviceType::ACCEL_UNCALIBRATED:
    case cros::mojom::DeviceType::ANGLVEL_UNCALIBRATED:
    case cros::mojom::DeviceType::MAGN_UNCALIBRATED:
      // TODO(chenghaoyang): uncalibrated devices will be generated by
      // iioservice instead of kernel.
    default:
      return std::nullopt;
  }
}

cros::mojom::IioChanType ConvertChanType(iio_chan_type chan_type) {
  switch (chan_type) {
    case iio_chan_type::IIO_PROXIMITY:
      return cros::mojom::IioChanType::IIO_PROXIMITY;

    default:
      NOTREACHED() << "Invalid iio_chan_type: " << chan_type;
      return cros::mojom::IioChanType::IIO_PROXIMITY;
  }
}

cros::mojom::IioEventType ConvertEventType(iio_event_type event_type) {
  switch (event_type) {
    case iio_event_type::IIO_EV_TYPE_THRESH:
      return cros::mojom::IioEventType::IIO_EV_TYPE_THRESH;

    case iio_event_type::IIO_EV_TYPE_MAG:
      return cros::mojom::IioEventType::IIO_EV_TYPE_MAG;

    case iio_event_type::IIO_EV_TYPE_ROC:
      return cros::mojom::IioEventType::IIO_EV_TYPE_ROC;

    case iio_event_type::IIO_EV_TYPE_THRESH_ADAPTIVE:
      return cros::mojom::IioEventType::IIO_EV_TYPE_THRESH_ADAPTIVE;

    case iio_event_type::IIO_EV_TYPE_MAG_ADAPTIVE:
      return cros::mojom::IioEventType::IIO_EV_TYPE_MAG_ADAPTIVE;

    case iio_event_type::IIO_EV_TYPE_CHANGE:
      return cros::mojom::IioEventType::IIO_EV_TYPE_CHANGE;

    default:
      NOTREACHED() << "Invalid iio_event_type: " << event_type;
      return cros::mojom::IioEventType::IIO_EV_TYPE_THRESH;
  }
}

cros::mojom::IioEventDirection ConvertDirection(iio_event_direction direction) {
  switch (direction) {
    case iio_event_direction::IIO_EV_DIR_EITHER:
      return cros::mojom::IioEventDirection::IIO_EV_DIR_EITHER;

    case iio_event_direction::IIO_EV_DIR_RISING:
      return cros::mojom::IioEventDirection::IIO_EV_DIR_RISING;

    case iio_event_direction::IIO_EV_DIR_FALLING:
      return cros::mojom::IioEventDirection::IIO_EV_DIR_FALLING;

    case iio_event_direction::IIO_EV_DIR_NONE:
      return cros::mojom::IioEventDirection::IIO_EV_DIR_NONE;

    default:
      NOTREACHED() << "Invalid iio_event_direction: " << direction;
      return cros::mojom::IioEventDirection::IIO_EV_DIR_EITHER;
  }
}

}  // namespace iioservice
