/*
 * Copyright (C) 2019 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.vibrator@1.3-service.redfin"

#include "Hardware.h"

#include <log/log.h>

#include <iostream>

namespace android {
namespace hardware {
namespace vibrator {
namespace V1_3 {
namespace implementation {

template <typename T>
static void fileFromEnv(const char *env, T *outStream, std::string *outName = nullptr) {
    auto file = std::getenv(env);
    auto mode = std::is_base_of_v<std::ostream, T> ? std::ios_base::out : std::ios_base::in;

    if (file == nullptr) {
        ALOGE("Failed get env %s", env);
        return;
    }

    if (outName != nullptr) {
        *outName = std::string(file);
    }

    // Force 'in' mode to prevent file creation
    outStream->open(file, mode | std::ios_base::in);
    if (!*outStream) {
        ALOGE("Failed to open %s:%s (%d): %s", env, file, errno, strerror(errno));
    }
}

static auto pathsFromEnv(const char *env) {
    std::map<std::string, std::ifstream> ret;
    auto value = std::getenv(env);

    if (value == nullptr) {
        return ret;
    }

    std::istringstream paths{value};
    std::string path;

    while (paths >> path) {
        ret[path].open(path);
    }

    return ret;
}

static std::string trim(const std::string &str, const std::string &whitespace = " \t") {
    const auto str_begin = str.find_first_not_of(whitespace);
    if (str_begin == std::string::npos) {
        return "";
    }

    const auto str_end = str.find_last_not_of(whitespace);
    const auto str_range = str_end - str_begin + 1;

    return str.substr(str_begin, str_range);
}

template <typename T>
static Enable_If_Iterable<T, true> unpack(std::istream &stream, T *value) {
    for (auto &entry : *value) {
        stream >> entry;
    }
}

template <typename T>
static Enable_If_Iterable<T, false> unpack(std::istream &stream, T *value) {
    stream >> *value;
}

HwApi::HwApi() {
    // ostreams below are required
    fileFromEnv("F0_FILEPATH", &mF0, &mNames[&mF0]);
    fileFromEnv("REDC_FILEPATH", &mRedc, &mNames[&mRedc]);
    fileFromEnv("Q_FILEPATH", &mQ, &mNames[&mQ]);
    fileFromEnv("ACTIVATE_PATH", &mActivate, &mNames[&mActivate]);
    fileFromEnv("DURATION_PATH", &mDuration, &mNames[&mDuration]);
    fileFromEnv("STATE_PATH", &mState, &mNames[&mState]);
    fileFromEnv("EFFECT_DURATION_PATH", &mEffectDuration, &mNames[&mEffectDuration]);
    fileFromEnv("EFFECT_INDEX_PATH", &mEffectIndex, &mNames[&mEffectIndex]);
    fileFromEnv("EFFECT_QUEUE_PATH", &mEffectQueue, &mNames[&mEffectQueue]);
    fileFromEnv("EFFECT_SCALE_PATH", &mEffectScale, &mNames[&mEffectScale]);
    fileFromEnv("GLOBAL_SCALE_PATH", &mGlobalScale, &mNames[&mGlobalScale]);
    fileFromEnv("ASP_ENABLE_PATH", &mAspEnable, &mNames[&mAspEnable]);
    fileFromEnv("GPIO_FALL_INDEX", &mGpioFallIndex, &mNames[&mGpioFallIndex]);
    fileFromEnv("GPIO_FALL_SCALE", &mGpioFallScale, &mNames[&mGpioFallScale]);
    fileFromEnv("GPIO_RISE_INDEX", &mGpioRiseIndex, &mNames[&mGpioRiseIndex]);
    fileFromEnv("GPIO_RISE_SCALE", &mGpioRiseScale, &mNames[&mGpioRiseScale]);
}

template <typename T>
bool HwApi::has(T &stream) {
    return !!stream;
}

template <typename T, typename U>
bool HwApi::get(T *value, U &stream) {
    bool ret;
    stream.seekg(0);
    stream >> *value;
    if (!(ret = !!stream)) {
        ALOGE("Failed to read %s (%d): %s", mNames[&stream].c_str(), errno, strerror(errno));
    }
    stream.clear();
    return ret;
}

template <typename T, typename U>
bool HwApi::set(const T &value, U &stream) {
    bool ret;
    stream << value << std::endl;
    if (!(ret = !!stream)) {
        ALOGE("Failed to write %s (%d): %s", mNames[&stream].c_str(), errno, strerror(errno));
        stream.clear();
    }
    return ret;
}

void HwApi::debug(int fd) {
    dprintf(fd, "Kernel:\n");

    for (auto &entry : pathsFromEnv("HWAPI_DEBUG_PATHS")) {
        auto &path = entry.first;
        auto &stream = entry.second;
        std::string line;

        dprintf(fd, "  %s:\n", path.c_str());
        while (std::getline(stream, line)) {
            dprintf(fd, "    %s\n", line.c_str());
        }
    }
}

HwCal::HwCal() {
    std::ifstream calfile;

    fileFromEnv("CALIBRATION_FILEPATH", &calfile);

    for (std::string line; std::getline(calfile, line);) {
        if (line.empty() || line[0] == '#') {
            continue;
        }
        std::istringstream is_line(line);
        std::string key, value;
        if (std::getline(is_line, key, ':') && std::getline(is_line, value)) {
            mCalData[trim(key)] = trim(value);
        }
    }
}

template <typename T>
bool HwCal::get(const char *key, T *value) {
    auto it = mCalData.find(key);
    if (it == mCalData.end()) {
        ALOGE("Missing %s config!", key);
        return false;
    }
    std::stringstream stream{it->second};
    unpack(stream, value);
    if (!stream || !stream.eof()) {
        ALOGE("Invalid %s config!", key);
        return false;
    }
    return true;
}

void HwCal::debug(int fd) {
    std::ifstream stream;
    std::string path;
    std::string line;

    dprintf(fd, "Persist:\n");

    fileFromEnv("CALIBRATION_FILEPATH", &stream, &path);

    dprintf(fd, "  %s:\n", path.c_str());
    while (std::getline(stream, line)) {
        dprintf(fd, "    %s\n", line.c_str());
    }
}

}  // namespace implementation
}  // namespace V1_3
}  // namespace vibrator
}  // namespace hardware
}  // namespace android
