/*
 * Copyright (C) 2021 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.
 */
#include "DevfreqStateResidencyDataProvider.h"

#include <android-base/logging.h>

static const std::string nameSuffix = "-DVFS";
static const std::string pathSuffix = "/time_in_state";

namespace aidl {
namespace android {
namespace hardware {
namespace power {
namespace stats {

DevfreqStateResidencyDataProvider::DevfreqStateResidencyDataProvider(const std::string& name,
        const std::string& path) : mName(name + nameSuffix), mPath(path + pathSuffix) {}

bool DevfreqStateResidencyDataProvider::extractNum(const char *str, char **str_end, int base,
        int64_t* num) {
    // errno can be set to any non-zero value by a library function call
    // regardless of whether there was an error, so it needs to be cleared
    // in order to check the error set by strtoll
    errno = 0;
    *num = std::strtoll(str, str_end, base);
    return (errno != ERANGE);
}

std::vector<std::pair<int64_t, int64_t>> DevfreqStateResidencyDataProvider::parseTimeInState() {
    // Using FILE* instead of std::ifstream for performance reasons
    std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(mPath.c_str(), "r"), fclose);
    if (!fp) {
        PLOG(ERROR) << "Failed to open file " << mPath;
        return {};
    }

    std::vector<std::pair<int64_t, int64_t>> timeInState;

    char *line = nullptr;
    size_t len = 0;
    while (getline(&line, &len, fp.get()) != -1) {
        char* pEnd;
        int64_t frequencyHz, totalTimeMs;
        if (!extractNum(line, &pEnd, 10, &frequencyHz) ||
            !extractNum(pEnd, &pEnd, 10, &totalTimeMs)) {
            PLOG(ERROR) << "Failed to parse " << mPath;
            free(line);
            return {};
        }

        timeInState.push_back({frequencyHz, totalTimeMs});
    }

    free(line);
    return timeInState;
}

bool DevfreqStateResidencyDataProvider::getStateResidencies(
        std::unordered_map<std::string, std::vector<StateResidency>> *residencies) {
    std::vector<std::pair<int64_t, int64_t>> timeInState = parseTimeInState();

    if (timeInState.empty()) {
        return false;
    }

    int32_t id = 0;
    std::vector<StateResidency> stateResidencies;
    for (const auto[frequencyHz, totalTimeMs] : timeInState) {
        StateResidency s = {.id = id++, .totalTimeInStateMs = totalTimeMs};
        stateResidencies.push_back(s);
    }

    residencies->emplace(mName, stateResidencies);
    return true;
}

std::unordered_map<std::string, std::vector<State>> DevfreqStateResidencyDataProvider::getInfo() {
    std::vector<std::pair<int64_t, int64_t>> timeInState = parseTimeInState();

    if (timeInState.empty()) {
        return {};
    }

    int32_t id = 0;
    std::vector<State> states;
    for (const auto[frequencyHz, totalTimeMs] : timeInState) {
        State s = {.id = id++, .name = std::to_string(frequencyHz / 1000) + "KHz"};
        states.push_back(s);
    }

    return {{mName, states}};
}

}  // namespace stats
}  // namespace power
}  // namespace hardware
}  // namespace android
}  // namespace aidl
