/*
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#define LOG_TAG "libpixelpowerstats"

#include <algorithm>
#include <thread>
#include <exception>
#include <inttypes.h>
#include <stdlib.h>
#include <android-base/file.h>
#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <android-base/stringprintf.h>
#include "RailDataProvider.h"

namespace android {
namespace hardware {
namespace google {
namespace pixel {
namespace powerstats {

#define MAX_FILE_PATH_LEN 128
#define MAX_DEVICE_NAME_LEN 64
#define MAX_QUEUE_SIZE 8192

constexpr char kIioDirRoot[] = "/sys/bus/iio/devices/";
constexpr char kDeviceName[] = "microchip,pac1934";
constexpr char kDeviceType[] = "iio:device";
constexpr uint32_t MAX_SAMPLING_RATE = 10;
constexpr uint64_t WRITE_TIMEOUT_NS = 1000000000;

void RailDataProvider::findIioPowerMonitorNodes() {
  struct dirent *ent;
  int fd;
  char devName[MAX_DEVICE_NAME_LEN];
  char filePath[MAX_FILE_PATH_LEN];
  DIR *iioDir = opendir(kIioDirRoot);
  if (!iioDir) {
    ALOGE("Error opening directory: %s, error: %d", kIioDirRoot, errno);
    return;
  }
  while (ent = readdir(iioDir), ent) {
    if (strcmp(ent->d_name, ".") != 0 &&
        strcmp(ent->d_name, "..") != 0 &&
        strlen(ent->d_name) > strlen(kDeviceType) &&
        strncmp(ent->d_name, kDeviceType, strlen(kDeviceType)) == 0) {

      snprintf(filePath, MAX_FILE_PATH_LEN, "%s/%s", ent->d_name, "name");
      fd = openat(dirfd(iioDir), filePath, O_RDONLY);
      if (fd < 0) {
        ALOGW("Failed to open directory: %s, error: %d", filePath, errno);
        continue;
      }
      if (read(fd, devName, MAX_DEVICE_NAME_LEN) < 0) {
        ALOGW("Failed to read device name from file: %s(%d)",
              filePath, fd);
        close(fd);
        continue;
      }

      if (strncmp(devName, kDeviceName, strlen(kDeviceName)) == 0) {
        snprintf(filePath, MAX_FILE_PATH_LEN, "%s/%s", kIioDirRoot, ent->d_name);
        mOdpm.devicePaths.push_back(filePath);
      }
      close(fd);
    }
  }
  closedir(iioDir);
  return;
}

size_t RailDataProvider::parsePowerRails() {
  std::string data;
  std::string railFileName;
  std::string spsFileName;
  uint32_t index = 0;
  uint32_t samplingRate;
  for (const auto &path : mOdpm.devicePaths) {
    railFileName = path + "/enabled_rails";
    spsFileName = path + "/sampling_rate";
    if (!android::base::ReadFileToString(spsFileName, &data)) {
      ALOGW("Error reading file: %s", spsFileName.c_str());
      continue;
    }
    samplingRate = strtoul(data.c_str(), NULL, 10);
    if (!samplingRate || samplingRate == ULONG_MAX) {
      ALOGE("Error parsing: %s", spsFileName.c_str());
      break;
    }
    if (!android::base::ReadFileToString(railFileName, &data)) {
      ALOGW("Error reading file: %s", railFileName.c_str());
      continue;
    }
    std::istringstream railNames(data);
    std::string line;
    while (std::getline(railNames, line)) {
      std::vector<std::string> words = android::base::Split(line, ":");
      if (words.size() == 2) {
        mOdpm.railsInfo.emplace(words[0],
                           RailData {
                             .devicePath = path,
                             .index = index,
                             .subsysName = words[1],
                             .samplingRate = samplingRate
                           });
        index++;
      } else {
        ALOGW("Unexpected format in file: %s", railFileName.c_str());
      }
    }
  }
  return index;
}

int RailDataProvider::parseIioEnergyNode(std::string devName) {
   int ret = 0;
   std::string data;
   std::string fileName = devName + "/energy_value";
   if (!android::base::ReadFileToString(fileName, &data)) {
     ALOGE("Error reading file: %s", fileName.c_str());
     return -1;
   }

   std::istringstream energyData(data);
   std::string line;
   uint64_t timestamp = 0;
   bool timestampRead = false;
   while (std::getline(energyData, line)) {
     std::vector<std::string> words = android::base::Split(line, ",");
     if (timestampRead == false) {
       if (words.size() == 1) {
         timestamp = strtoull(words[0].c_str(), NULL, 10);
         if (timestamp == 0 || timestamp == ULLONG_MAX) {
           ALOGW("Potentially wrong timestamp: %" PRIu64, timestamp);
         }
         timestampRead = true;
       }
     } else if (words.size() == 2) {
         std::string railName = words[0];
         if (mOdpm.railsInfo.count(railName) != 0) {
           size_t index = mOdpm.railsInfo[railName].index;
           mOdpm.reading[index].index = index;
           mOdpm.reading[index].timestamp = timestamp;
           mOdpm.reading[index].energy = strtoull(words[1].c_str(), NULL, 10);
           if (mOdpm.reading[index].energy == ULLONG_MAX) {
             ALOGW("Potentially wrong energy value: %" PRIu64,
                   mOdpm.reading[index].energy);
           }
         }
     } else {
       ALOGW("Unexpected format in file: %s", fileName.c_str());
       ret = -1;
       break;
     }
   }
   return ret;
}

Status RailDataProvider::parseIioEnergyNodes() {
  Status ret = Status::SUCCESS;
  if (mOdpm.hwEnabled == false) {
    return Status::NOT_SUPPORTED;
  }

  for (const auto &devicePath : mOdpm.devicePaths) {
    if(parseIioEnergyNode(devicePath) < 0) {
      ALOGE("Error in parsing power stats");
      ret = Status::FILESYSTEM_ERROR;
      break;
    }
  }
  return ret;
}

RailDataProvider::RailDataProvider() {
    findIioPowerMonitorNodes();
    size_t numRails = parsePowerRails();
    if (mOdpm.devicePaths.empty() || numRails == 0) {
      mOdpm.hwEnabled = false;
    } else {
      mOdpm.hwEnabled = true;
      mOdpm.reading.resize(numRails);
    }
}

Return<void> RailDataProvider::getRailInfo(IPowerStats::getRailInfo_cb _hidl_cb) {
  hidl_vec<RailInfo> rInfo;
  Status ret = Status::SUCCESS;
  size_t index;
  std::lock_guard<std::mutex> _lock(mOdpm.mLock);
  if (mOdpm.hwEnabled == false) {
    ALOGI("getRailInfo not supported");
    _hidl_cb(rInfo, Status::NOT_SUPPORTED);
    return Void();
  }
  rInfo.resize(mOdpm.railsInfo.size());
  for (const auto& railData : mOdpm.railsInfo) {
    index = railData.second.index;
    rInfo[index].railName = railData.first;
    rInfo[index].subsysName = railData.second.subsysName;
    rInfo[index].index = index;
    rInfo[index].samplingRate = railData.second.samplingRate;
  }
  _hidl_cb(rInfo, ret);
  return Void();
}

Return<void> RailDataProvider::getEnergyData(const hidl_vec<uint32_t>& railIndices, IPowerStats::getEnergyData_cb _hidl_cb) {
  hidl_vec<EnergyData> eVal;
  std::lock_guard<std::mutex> _lock(mOdpm.mLock);
  Status ret = parseIioEnergyNodes();

  if (ret != Status::SUCCESS) {
    _hidl_cb(eVal, ret);
    return Void();
  }

  if (railIndices.size() == 0) {
    eVal.resize(mOdpm.railsInfo.size());
    memcpy(&eVal[0], &mOdpm.reading[0], mOdpm.reading.size() * sizeof(EnergyData));
  } else {
    eVal.resize(railIndices.size());
    int i = 0;
    for (const auto &railIndex : railIndices) {
      if (railIndex >= mOdpm.reading.size()) {
        ret = Status::INVALID_INPUT;
        eVal.resize(0);
        break;
      }
      memcpy(&eVal[i], &mOdpm.reading[railIndex], sizeof(EnergyData));
      i++;
    }
  }
  _hidl_cb(eVal, ret);
  return Void();
}

Return<void> RailDataProvider::streamEnergyData(uint32_t timeMs, uint32_t samplingRate,
                                IPowerStats::streamEnergyData_cb _hidl_cb) {
  std::lock_guard<std::mutex> _lock(mOdpm.mLock);
  if (mOdpm.fmqSynchronized != nullptr) {
    _hidl_cb(MessageQueueSync::Descriptor(),
             0, 0, Status::INSUFFICIENT_RESOURCES);
    return Void();
  }
  uint32_t sps = std::min(samplingRate, MAX_SAMPLING_RATE);
  uint32_t numSamples = timeMs * sps / 1000;
  mOdpm.fmqSynchronized.reset(new (std::nothrow) MessageQueueSync(MAX_QUEUE_SIZE, true));
  if (mOdpm.fmqSynchronized == nullptr || mOdpm.fmqSynchronized->isValid() == false) {
    mOdpm.fmqSynchronized = nullptr;
    _hidl_cb(MessageQueueSync::Descriptor(),
             0, 0, Status::INSUFFICIENT_RESOURCES);
    return Void();
  }
  std::thread pollThread = std::thread([this, sps, numSamples]() {
    uint64_t sleepTimeUs = 1000000/sps;
    uint32_t currSamples = 0;
    while (currSamples < numSamples) {
      mOdpm.mLock.lock();
      if (parseIioEnergyNodes() == Status::SUCCESS) {
        mOdpm.fmqSynchronized->writeBlocking(&mOdpm.reading[0],
                                             mOdpm.reading.size(), WRITE_TIMEOUT_NS);
        mOdpm.mLock.unlock();
        currSamples++;
        if (usleep(sleepTimeUs) < 0) {
          ALOGW("Sleep interrupted");
          break;
        }
      } else {
        mOdpm.mLock.unlock();
        break;
      }
    }
    mOdpm.mLock.lock();
    mOdpm.fmqSynchronized = nullptr;
    mOdpm.mLock.unlock();
    return;
  });
  pollThread.detach();
  _hidl_cb(*(mOdpm.fmqSynchronized)->getDesc(), numSamples,
           mOdpm.reading.size(), Status::SUCCESS);
  return Void();
}

}  // namespace powerstats
}  // namespace pixel
}  // namespace google
}  // namespace hardware
}  // namespace android
