/*
 * 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 "android.hardware.power.stats@1.0-service-mock"

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

namespace android {
namespace hardware {
namespace power {
namespace stats {
namespace V1_0 {
namespace implementation {

#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[] = "pm_device_name";
constexpr char kDeviceType[] = "iio:device";
constexpr uint32_t MAX_SAMPLING_RATE = 10;
constexpr uint64_t WRITE_TIMEOUT_NS = 1000000000;

void PowerStats::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", kIioDirRoot);
        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", filePath);
                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);
                mPm.devicePaths.push_back(filePath);
            }
            close(fd);
        }
    }
    closedir(iioDir);
    return;
}

size_t PowerStats::parsePowerRails() {
    std::string data;
    std::string railFileName;
    std::string spsFileName;
    uint32_t index = 0;
    unsigned long samplingRate;
    for (const auto& path : mPm.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) {
                mPm.railsInfo.emplace(
                        words[0], RailData{.devicePath = path,
                                           .index = index,
                                           .subsysName = words[1],
                                           .samplingRate = static_cast<uint32_t>(samplingRate)});
                index++;
            } else {
                ALOGW("Unexpected format in file: %s", railFileName.c_str());
            }
        }
    }
    return index;
}

int PowerStats::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 (mPm.railsInfo.count(railName) != 0) {
                size_t index = mPm.railsInfo[railName].index;
                mPm.reading[index].index = index;
                mPm.reading[index].timestamp = timestamp;
                mPm.reading[index].energy = strtoull(words[1].c_str(), NULL, 10);
                if (mPm.reading[index].energy == ULLONG_MAX) {
                    ALOGW("Potentially wrong energy value: %" PRIu64, mPm.reading[index].energy);
                }
            }
        } else {
            ALOGW("Unexpected format in file: %s", fileName.c_str());
            ret = -1;
            break;
        }
    }
    return ret;
}

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

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

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

Return<void> PowerStats::getRailInfo(getRailInfo_cb _hidl_cb) {
    hidl_vec<RailInfo> rInfo;
    Status ret = Status::SUCCESS;
    size_t index;
    std::lock_guard<std::mutex> _lock(mPm.mLock);
    if (mPm.hwEnabled == false) {
        _hidl_cb(rInfo, Status::NOT_SUPPORTED);
        return Void();
    }
    rInfo.resize(mPm.railsInfo.size());
    for (const auto& railData : mPm.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> PowerStats::getEnergyData(const hidl_vec<uint32_t>& railIndices,
                                       getEnergyData_cb _hidl_cb) {
    hidl_vec<EnergyData> eVal;
    std::lock_guard<std::mutex> _lock(mPm.mLock);
    Status ret = parseIioEnergyNodes();

    if (ret != Status::SUCCESS) {
        ALOGE("Failed to getEnergyData");
        _hidl_cb(eVal, ret);
        return Void();
    }

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

Return<void> PowerStats::streamEnergyData(uint32_t timeMs, uint32_t samplingRate,
                                          streamEnergyData_cb _hidl_cb) {
    std::lock_guard<std::mutex> _lock(mPm.mLock);
    if (mPm.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;
    mPm.fmqSynchronized.reset(new (std::nothrow) MessageQueueSync(MAX_QUEUE_SIZE, true));
    if (mPm.fmqSynchronized == nullptr || mPm.fmqSynchronized->isValid() == false) {
        mPm.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) {
            mPm.mLock.lock();
            if (parseIioEnergyNodes() == Status::SUCCESS) {
                mPm.fmqSynchronized->writeBlocking(&mPm.reading[0], mPm.reading.size(),
                                                   WRITE_TIMEOUT_NS);
                mPm.mLock.unlock();
                currSamples++;
                if (usleep(sleepTimeUs) < 0) {
                    ALOGW("Sleep interrupted");
                    break;
                }
            } else {
                mPm.mLock.unlock();
                break;
            }
        }
        mPm.mLock.lock();
        mPm.fmqSynchronized = nullptr;
        mPm.mLock.unlock();
        return;
    });
    pollThread.detach();
    _hidl_cb(*(mPm.fmqSynchronized)->getDesc(), numSamples, mPm.reading.size(), Status::SUCCESS);
    return Void();
}

uint32_t PowerStats::addPowerEntity(const std::string& name, PowerEntityType type) {
    uint32_t id = mPowerEntityInfos.size();
    mPowerEntityInfos.push_back({id, name, type});
    return id;
}

void PowerStats::addStateResidencyDataProvider(std::shared_ptr<IStateResidencyDataProvider> p) {
    std::vector<PowerEntityStateSpace> stateSpaces = p->getStateSpaces();
    for (auto stateSpace : stateSpaces) {
        mPowerEntityStateSpaces.emplace(stateSpace.powerEntityId, stateSpace);
        mStateResidencyDataProviders.emplace(stateSpace.powerEntityId, p);
    }
}

Return<void> PowerStats::getPowerEntityInfo(getPowerEntityInfo_cb _hidl_cb) {
    // If not configured, return NOT_SUPPORTED
    if (mPowerEntityInfos.empty()) {
        _hidl_cb({}, Status::NOT_SUPPORTED);
        return Void();
    }

    _hidl_cb(mPowerEntityInfos, Status::SUCCESS);
    return Void();
}

Return<void> PowerStats::getPowerEntityStateInfo(const hidl_vec<uint32_t>& powerEntityIds,
                                                 getPowerEntityStateInfo_cb _hidl_cb) {
    // If not configured, return NOT_SUPPORTED
    if (mPowerEntityStateSpaces.empty()) {
        _hidl_cb({}, Status::NOT_SUPPORTED);
        return Void();
    }

    std::vector<PowerEntityStateSpace> stateSpaces;

    // If powerEntityIds is empty then return state space info for all entities
    if (powerEntityIds.size() == 0) {
        stateSpaces.reserve(mPowerEntityStateSpaces.size());
        for (auto i : mPowerEntityStateSpaces) {
            stateSpaces.emplace_back(i.second);
        }
        _hidl_cb(stateSpaces, Status::SUCCESS);
        return Void();
    }

    // Return state space information only for valid ids
    auto ret = Status::SUCCESS;
    stateSpaces.reserve(powerEntityIds.size());
    for (const uint32_t id : powerEntityIds) {
        auto stateSpace = mPowerEntityStateSpaces.find(id);
        if (stateSpace != mPowerEntityStateSpaces.end()) {
            stateSpaces.emplace_back(stateSpace->second);
        } else {
            ret = Status::INVALID_INPUT;
        }
    }

    _hidl_cb(stateSpaces, ret);
    return Void();
}

Return<void> PowerStats::getPowerEntityStateResidencyData(
        const hidl_vec<uint32_t>& powerEntityIds, getPowerEntityStateResidencyData_cb _hidl_cb) {
    // If not configured, return NOT_SUPPORTED
    if (mStateResidencyDataProviders.empty() || mPowerEntityStateSpaces.empty()) {
        _hidl_cb({}, Status::NOT_SUPPORTED);
        return Void();
    }

    // If powerEntityIds is empty then return data for all supported entities
    if (powerEntityIds.size() == 0) {
        std::vector<uint32_t> ids;
        for (auto stateSpace : mPowerEntityStateSpaces) {
            ids.emplace_back(stateSpace.first);
        }
        return getPowerEntityStateResidencyData(ids, _hidl_cb);
    }

    std::unordered_map<uint32_t, PowerEntityStateResidencyResult> stateResidencies;
    std::vector<PowerEntityStateResidencyResult> results;
    results.reserve(powerEntityIds.size());

    // return results for only the given powerEntityIds
    bool invalidInput = false;
    bool filesystemError = false;
    for (auto id : powerEntityIds) {
        auto dataProvider = mStateResidencyDataProviders.find(id);
        // skip if the given powerEntityId does not have an associated StateResidencyDataProvider
        if (dataProvider == mStateResidencyDataProviders.end()) {
            invalidInput = true;
            continue;
        }

        // get the results if we have not already done so.
        if (stateResidencies.find(id) == stateResidencies.end()) {
            if (!dataProvider->second->getResults(stateResidencies)) {
                filesystemError = true;
            }
        }

        // append results
        auto stateResidency = stateResidencies.find(id);
        if (stateResidency != stateResidencies.end()) {
            results.emplace_back(stateResidency->second);
        }
    }

    auto ret = Status::SUCCESS;
    if (filesystemError) {
        ret = Status::FILESYSTEM_ERROR;
    } else if (invalidInput) {
        ret = Status::INVALID_INPUT;
    }

    _hidl_cb(results, ret);
    return Void();
}

bool DumpResidencyDataToFd(const hidl_vec<PowerEntityInfo>& infos,
                           const hidl_vec<PowerEntityStateSpace>& stateSpaces,
                           const hidl_vec<PowerEntityStateResidencyResult>& results, int fd) {
    // construct lookup table of powerEntityId to name
    std::unordered_map<uint32_t, std::string> entityNames;
    for (auto info : infos) {
        entityNames.emplace(info.powerEntityId, info.powerEntityName);
    }

    // construct lookup table of powerEntityId, powerEntityStateId to state name
    std::unordered_map<uint32_t, std::unordered_map<uint32_t, std::string>> stateNames;
    for (auto stateSpace : stateSpaces) {
        stateNames.emplace(stateSpace.powerEntityId, std::unordered_map<uint32_t, std::string>());
        for (auto state : stateSpace.states) {
            stateNames.at(stateSpace.powerEntityId)
                    .emplace(state.powerEntityStateId, state.powerEntityStateName);
        }
    }

    std::ostringstream dumpStats;
    dumpStats << "\n========== PowerStats HAL 1.0 state residencies ==========\n";

    const char* headerFormat = "  %14s   %14s   %16s   %15s   %16s\n";
    const char* dataFormat =
            "  %14s   %14s   %13" PRIu64 " ms   %15" PRIu64 "   %13" PRIu64 " ms\n";
    dumpStats << android::base::StringPrintf(headerFormat, "Entity", "State", "Total time",
                                             "Total entries", "Last entry timestamp");

    for (auto result : results) {
        for (auto stateResidency : result.stateResidencyData) {
            dumpStats << android::base::StringPrintf(
                    dataFormat, entityNames.at(result.powerEntityId).c_str(),
                    stateNames.at(result.powerEntityId)
                            .at(stateResidency.powerEntityStateId)
                            .c_str(),
                    stateResidency.totalTimeInStateMs, stateResidency.totalStateEntryCount,
                    stateResidency.lastEntryTimestampMs);
        }
    }

    dumpStats << "========== End of PowerStats HAL 1.0 state residencies ==========\n";

    return android::base::WriteStringToFd(dumpStats.str(), fd);
}

Return<void> PowerStats::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
    if (handle == nullptr || handle->numFds < 1) {
        return Void();
    }

    int fd = handle->data[0];
    Status status;
    hidl_vec<PowerEntityInfo> infos;

    // Get power entity information
    getPowerEntityInfo([&status, &infos](auto rInfos, auto rStatus) {
        status = rStatus;
        infos = rInfos;
    });
    if (status != Status::SUCCESS) {
        LOG(ERROR) << "Error getting power entity info";
        return Void();
    }

    // Get power entity state information
    hidl_vec<PowerEntityStateSpace> stateSpaces;
    getPowerEntityStateInfo({}, [&status, &stateSpaces](auto rStateSpaces, auto rStatus) {
        status = rStatus;
        stateSpaces = rStateSpaces;
    });
    if (status != Status::SUCCESS) {
        LOG(ERROR) << "Error getting state info";
        return Void();
    }

    // Get power entity state residency data
    hidl_vec<PowerEntityStateResidencyResult> results;
    getPowerEntityStateResidencyData({}, [&status, &results](auto rResults, auto rStatus) {
        status = rStatus;
        results = rResults;
    });

    // This implementation of getPowerEntityStateResidencyData supports the
    // return of partial results if status == FILESYSTEM_ERROR.
    if (status != Status::SUCCESS) {
        LOG(ERROR) << "Error getting residency data -- Some results missing";
    }

    if (!DumpResidencyDataToFd(infos, stateSpaces, results, fd)) {
        PLOG(ERROR) << "Failed to dump residency data to fd";
    }

    fsync(fd);

    return Void();
}

}  // namespace implementation
}  // namespace V1_0
}  // namespace stats
}  // namespace power
}  // namespace hardware
}  // namespace android
