/*
 * Copyright (C) 2020 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 "dChargerDetect"

#include <android-base/file.h>
#include <android-base/parseint.h>
#include <android-base/strings.h>
#include <cutils/klog.h>
#include <dirent.h>
#include <pixelhealth/ChargerDetect.h>
#include <pixelhealth/HealthHelper.h>

#include <string>

constexpr char kPowerSupplySysfsPath[]{"/sys/class/power_supply/"};
constexpr char kUsbOnlinePath[]{"/sys/class/power_supply/usb/online"};
constexpr char kUsbPowerSupplySysfsPath[]{"/sys/class/power_supply/usb/usb_type"};
constexpr char kTcpmPsyFilter[]{"tcpm"};
using aidl::android::hardware::health::HealthInfo;
using android::BatteryMonitor;

namespace hardware {
namespace google {
namespace pixel {
namespace health {

int ChargerDetect::readFromFile(const std::string& path, std::string* buf) {
    if (android::base::ReadFileToString(path.c_str(), buf)) {
        *buf = android::base::Trim(*buf);
    }
    return buf->length();
}

int ChargerDetect::getIntField(const std::string& path) {
    std::string buf;
    int value = 0;

    if (readFromFile(path, &buf) > 0)
        android::base::ParseInt(buf, &value);

    return value;
}

/*
 * Traverses through /sys/class/power_supply/ to identify TCPM(Type-C/PD) power supply.
 * TCPM power supply's name follows the format "tcpm-source-psy-6-0025" with i2c/i3c bus id
 * and client id(SID) baked in.
 */
void ChargerDetect::populateTcpmPsyName(std::string* tcpmPsyName) {
    std::unique_ptr<DIR, decltype(&closedir)> dir(opendir(kPowerSupplySysfsPath), closedir);
    if (dir == NULL) {
            KLOG_ERROR(LOG_TAG, "Could not open %s\n", kPowerSupplySysfsPath);
    } else {
        struct dirent* entry;

        while ((entry = readdir(dir.get()))) {
            const char* name = entry->d_name;

            KLOG_INFO(LOG_TAG, "Psy name:%s", name);
            if (strstr(name, kTcpmPsyFilter)) {
                *tcpmPsyName = name;
            }
        }
    }
}

/*
 * The contents of /sys/class/power_supply/<Power supply name>/usb_type follows the format:
 * Unknown [SDP] CDP DCP
 * with the current selected value encloses within square braces.
 * This functions extracts the current selected value and returns it back to the caller.
 */
int ChargerDetect::getPsyUsbType(const std::string& path, std::string* type) {
    size_t start;
    std::string usbType;
    int ret;

    ret = readFromFile(path, &usbType);
    if (ret <= 0) {
        KLOG_ERROR(LOG_TAG, "Error reading %s: %d\n", path.c_str(), ret);
        return -EINVAL;
    }

    start = usbType.find('[');
    if (start == std::string::npos) {
        KLOG_ERROR(LOG_TAG, "'[' not found in %s: %s\n", path.c_str(), usbType.c_str());
        return -EINVAL;
    }

    *type = usbType.substr(start + 1, usbType.find(']') - start - 1);
    return 0;
}

/*
 * Reads the usb power_supply's usb_type and the tcpm power_supply's usb_type to infer
 * HealthInfo(hardware/interfaces/health/1.0/types.hal) online property.
 */
void ChargerDetect::onlineUpdate(HealthInfo *health_info) {
    std::string tcpmOnlinePath, usbPsyType;
    static std::string tcpmPsyName;
    int ret;

    health_info->chargerAcOnline = false;
    health_info->chargerUsbOnline = false;

    if (tcpmPsyName.empty()) {
        populateTcpmPsyName(&tcpmPsyName);
        KLOG_INFO(LOG_TAG, "TcpmPsyName:%s\n", tcpmPsyName.c_str());
    }

    if (!getIntField(kUsbOnlinePath)) {
        return;
    }

    ret = getPsyUsbType(kUsbPowerSupplySysfsPath, &usbPsyType);
    if (!ret) {
        if (usbPsyType == "CDP" || usbPsyType == "DCP") {
            health_info->chargerAcOnline = true;
            return;
        } else if (usbPsyType == "SDP") {
            health_info->chargerUsbOnline = true;
            return;
        }
    }

    /* Safe to assume AC charger here if BC1.2 non compliant */
    health_info->chargerAcOnline = true;

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

    ret = getPsyUsbType(std::string(kPowerSupplySysfsPath) + tcpmPsyName + "/usb_type",
                        &usbPsyType);
    if (ret < 0) {
        return;
    }

    KLOG_INFO(LOG_TAG, "TcpmPsy Usbtype:%s\n", usbPsyType.c_str());

    return;
}

void ChargerDetect::onlineUpdate(struct android::BatteryProperties *props) {
    HealthInfo health_info = ToHealthInfo(props);
    onlineUpdate(&health_info);
    // Propagate the changes to props
    props->chargerAcOnline = health_info.chargerAcOnline;
    props->chargerUsbOnline = health_info.chargerUsbOnline;
    // onlineUpdate doesn't change chargerWirelessOnline and other fields.
}

}  // namespace health
}  // namespace pixel
}  // namespace google
}  // namespace hardware
