/*
 * 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.health@2.0-service.wahoo"
#include <android-base/logging.h>

#include <healthd/healthd.h>
#include <health2/Health.h>
#include <health2/service.h>
#include <hidl/HidlTransportSupport.h>

#include <android-base/file.h>
#include <android-base/strings.h>

#include <vector>
#include <string>

#include "CycleCountBackupRestore.h"
#include "LearnedCapacityBackupRestore.h"

using android::hardware::health::V2_0::StorageInfo;
using android::hardware::health::V2_0::DiskStats;
using ::device::google::wahoo::health::CycleCountBackupRestore;
using ::device::google::wahoo::health::LearnedCapacityBackupRestore;

static constexpr int kBackupTrigger = 20;
static CycleCountBackupRestore ccBackupRestore;
static LearnedCapacityBackupRestore lcBackupRestore;

int cycle_count_backup(int battery_level)
{
    static int saved_soc = 0;
    static int soc_inc = 0;
    static bool is_first = true;

    if (is_first) {
        is_first = false;
        saved_soc = battery_level;
        return 0;
    }

    if (battery_level > saved_soc) {
        soc_inc += battery_level - saved_soc;
    }

    saved_soc = battery_level;

    if (soc_inc >= kBackupTrigger) {
        ccBackupRestore.Backup();
        soc_inc = 0;
    }
    return 0;
}

// See : hardware/interfaces/health/2.0/README

void healthd_board_init(struct healthd_config*)
{
    ccBackupRestore.Restore();
    lcBackupRestore.Restore();
}

int healthd_board_battery_update(struct android::BatteryProperties *props)
{
    cycle_count_backup(props->batteryLevel);
    lcBackupRestore.Backup();
    return 0;
}

const char kUFSHealthFile[] = "/sys/kernel/debug/ufshcd0/dump_health_desc";
const char kUFSHealthVersionFile[] = "/sys/kernel/debug/ufshcd0/show_hba";
const char kDiskStatsFile[] = "/sys/block/sda/stat";
const char kUFSName[] = "UFS0";

/*
 * Implementation based on system/core/storaged/storaged_info.cc
 */
void get_storage_info(std::vector<StorageInfo>& vec_storage_info) {
    StorageInfo storage_info = {};
    std::string buffer, version;

    storage_info.attr.isInternal = true;
    storage_info.attr.isBootDevice = true;
    storage_info.attr.name = std::string(kUFSName);

    if (!android::base::ReadFileToString(std::string(kUFSHealthVersionFile), &version)) {
        return;
    }

    std::vector<std::string> lines = android::base::Split(version, "\n");
    if (lines.empty()) {
        return;
    }

    char rev[8];
    if (sscanf(lines[6].c_str(), "hba->ufs_version = 0x%7s\n", rev) < 1) {
        return;
    }

    storage_info.version = "ufs " + std::string(rev);

    if (!android::base::ReadFileToString(std::string(kUFSHealthFile), &buffer)) {
        return;
    }

    lines = android::base::Split(buffer, "\n");
    if (lines.empty()) {
        return;
    }

    for (size_t i = 1; i < lines.size(); i++) {
        char token[32];
        uint16_t val;
        int ret;
        if ((ret = sscanf(lines[i].c_str(),
                   "Health Descriptor[Byte offset 0x%*d]: %31s = 0x%hx",
                   token, &val)) < 2) {
            continue;
        }

        if (std::string(token) == "bPreEOLInfo") {
            storage_info.eol = val;
        } else if (std::string(token) == "bDeviceLifeTimeEstA") {
            storage_info.lifetimeA = val;
        } else if (std::string(token) == "bDeviceLifeTimeEstB") {
            storage_info.lifetimeB = val;
        }
    }

    vec_storage_info.resize(1);
    vec_storage_info[0] = storage_info;
    return;
}

/*
 * Implementation based on parse_disk_stats() in system/core/storaged_diskstats.cpp
 */
void get_disk_stats(std::vector<DiskStats>& vec_stats) {
    const size_t kDiskStatsSize = 11;
    struct DiskStats stats = {};

    stats.attr.isInternal = true;
    stats.attr.isBootDevice = true;
    stats.attr.name = std::string(kUFSName);


    std::string buffer;
    if (!android::base::ReadFileToString(std::string(kDiskStatsFile), &buffer)) {
        LOG(ERROR) << kDiskStatsFile << ": ReadFileToString failed.";
        return;
    }

    // Regular diskstats entries
    std::stringstream ss(buffer);
    for (uint i = 0; i < kDiskStatsSize; ++i) {
        ss >> *(reinterpret_cast<uint64_t*>(&stats) + i);
    }
    vec_stats.resize(1);
    vec_stats[0] = stats;

    return;
}

int main(void) {
    return health_service_main();
}
