/*
 * 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 "thermal"

#include <cerrno>
#include <thread>
#include <limits>

#include <android/thermal.h>
#include <android/os/BnThermalStatusListener.h>
#include <android/os/IThermalService.h>
#include <binder/IServiceManager.h>
#include <utils/Log.h>

using android::sp;

using namespace android;
using namespace android::os;

struct ThermalServiceListener : public BnThermalStatusListener {
    public:
        virtual binder::Status onStatusChange(int32_t status) override;
        ThermalServiceListener(AThermalManager *manager) {mMgr = manager;}
    private:
        AThermalManager *mMgr;
};

struct ListenerCallback {
    AThermal_StatusCallback callback;
    void* data;
};

struct AThermalManager {
   public:
        static AThermalManager* createAThermalManager();
        AThermalManager() = delete;
        ~AThermalManager();
        status_t notifyStateChange(int32_t status);
        status_t getCurrentThermalStatus(int32_t *status);
        status_t addListener(AThermal_StatusCallback, void *data);
        status_t removeListener(AThermal_StatusCallback, void *data);
        status_t getThermalHeadroom(int32_t forecastSeconds, float *result);
   private:
       AThermalManager(sp<IThermalService> service);
       sp<IThermalService> mThermalSvc;
       sp<ThermalServiceListener> mServiceListener;
       std::vector<ListenerCallback> mListeners;
       std::mutex mMutex;
};

binder::Status ThermalServiceListener::onStatusChange(int32_t status) {
    if (mMgr != nullptr) {
        mMgr->notifyStateChange(status);
    }
    return binder::Status::ok();
}

AThermalManager* AThermalManager::createAThermalManager() {
    sp<IBinder> binder =
            defaultServiceManager()->checkService(String16("thermalservice"));

    if (binder == nullptr) {
        ALOGE("%s: Thermal service is not ready ", __FUNCTION__);
        return nullptr;
    }
    return new AThermalManager(interface_cast<IThermalService>(binder));
}

AThermalManager::AThermalManager(sp<IThermalService> service)
    : mThermalSvc(service),
      mServiceListener(nullptr) {
}

AThermalManager::~AThermalManager() {
    std::unique_lock<std::mutex> lock(mMutex);

    mListeners.clear();
    if (mServiceListener != nullptr) {
        bool success = false;
        mThermalSvc->unregisterThermalStatusListener(mServiceListener, &success);
        mServiceListener = nullptr;
    }
}

status_t AThermalManager::notifyStateChange(int32_t status) {
    std::unique_lock<std::mutex> lock(mMutex);
    AThermalStatus thermalStatus = static_cast<AThermalStatus>(status);

    for (auto listener : mListeners) {
        listener.callback(listener.data, thermalStatus);
    }
    return OK;
}

status_t AThermalManager::addListener(AThermal_StatusCallback callback, void *data) {
    std::unique_lock<std::mutex> lock(mMutex);

    if (callback == nullptr) {
        // Callback can not be nullptr
        return EINVAL;
    }
    for (const auto& cb : mListeners) {
        // Don't re-add callbacks.
        if (callback == cb.callback && data == cb.data) {
            return EINVAL;
        }
    }
    mListeners.emplace_back(ListenerCallback{callback, data});

    if (mServiceListener != nullptr) {
        return OK;
    }
    bool success = false;
    mServiceListener = new ThermalServiceListener(this);
    if (mServiceListener == nullptr) {
        return ENOMEM;
    }
    auto ret = mThermalSvc->registerThermalStatusListener(mServiceListener, &success);
    if (!success || !ret.isOk()) {
        ALOGE("Failed in registerThermalStatusListener %d", success);
        if (ret.exceptionCode() == binder::Status::EX_SECURITY) {
            return EPERM;
        }
        return EPIPE;
    }
    return OK;
}

status_t AThermalManager::removeListener(AThermal_StatusCallback callback, void *data) {
    std::unique_lock<std::mutex> lock(mMutex);

    auto it = std::remove_if(mListeners.begin(),
                             mListeners.end(),
                             [&](const ListenerCallback& cb) {
                                    return callback == cb.callback &&
                                           data == cb.data;
                             });
    if (it == mListeners.end()) {
        // If the listener and data pointer were not previously added.
        return EINVAL;
    }
    mListeners.erase(it, mListeners.end());

    if (!mListeners.empty()) {
        return OK;
    }
    if (mServiceListener == nullptr) {
        return OK;
    }
    bool success = false;
    auto ret = mThermalSvc->unregisterThermalStatusListener(mServiceListener, &success);
    if (!success || !ret.isOk()) {
        ALOGE("Failed in unregisterThermalStatusListener %d", success);
        if (ret.exceptionCode() == binder::Status::EX_SECURITY) {
            return EPERM;
        }
        return EPIPE;
    }
    mServiceListener = nullptr;
    return OK;
}

status_t AThermalManager::getCurrentThermalStatus(int32_t *status) {
    binder::Status ret = mThermalSvc->getCurrentThermalStatus(status);

    if (!ret.isOk()) {
        if (ret.exceptionCode() == binder::Status::EX_SECURITY) {
            return EPERM;
        }
        return EPIPE;
    }
    return OK;
}

status_t AThermalManager::getThermalHeadroom(int32_t forecastSeconds, float *result) {
    binder::Status ret = mThermalSvc->getThermalHeadroom(forecastSeconds, result);

    if (!ret.isOk()) {
        if (ret.exceptionCode() == binder::Status::EX_SECURITY) {
            return EPERM;
        }
        return EPIPE;
    }
    return OK;
}

/**
  * Acquire an instance of the thermal manager. This must be freed using
  * {@link AThermal_releaseManager}.
  *
  * @return manager instance on success, nullptr on failure.
 */
AThermalManager* AThermal_acquireManager() {
    auto manager = AThermalManager::createAThermalManager();

    return manager;
}

/**
 * Release the thermal manager pointer acquired by
 * {@link AThermal_acquireManager}.
 *
 * @param manager The manager to be released.
 *
 */
void AThermal_releaseManager(AThermalManager *manager) {
    delete manager;
}

/**
  * Gets the current thermal status.
  *
  * @param manager The manager instance to use to query the thermal status,
  * acquired by {@link AThermal_acquireManager}.
  *
  * @return current thermal status, ATHERMAL_STATUS_ERROR on failure.
*/
AThermalStatus AThermal_getCurrentThermalStatus(AThermalManager *manager) {
    int32_t status = 0;
    status_t ret = manager->getCurrentThermalStatus(&status);
    if (ret != OK) {
        return AThermalStatus::ATHERMAL_STATUS_ERROR;
    }
    return static_cast<AThermalStatus>(status);
}

/**
 * Register the thermal status listener for thermal status change.
 *
 * @param manager The manager instance to use to register.
 * acquired by {@link AThermal_acquireManager}.
 * @param callback The callback function to be called when thermal status updated.
 * @param data The data pointer to be passed when callback is called.
 *
 * @return 0 on success
 *         EINVAL if the listener and data pointer were previously added and not removed.
 *         EPERM if the required permission is not held.
 *         EPIPE if communication with the system service has failed.
 */
int AThermal_registerThermalStatusListener(AThermalManager *manager,
        AThermal_StatusCallback callback, void *data) {
    return manager->addListener(callback, data);
}

/**
 * Unregister the thermal status listener previously resgistered.
 *
 * @param manager The manager instance to use to unregister.
 * acquired by {@link AThermal_acquireManager}.
 * @param callback The callback function to be called when thermal status updated.
 * @param data The data pointer to be passed when callback is called.
 *
 * @return 0 on success
 *         EINVAL if the listener and data pointer were not previously added.
 *         EPERM if the required permission is not held.
 *         EPIPE if communication with the system service has failed.
 */
int AThermal_unregisterThermalStatusListener(AThermalManager *manager,
        AThermal_StatusCallback callback, void *data) {
    return manager->removeListener(callback, data);
}

/**
 * Provides an estimate of how much thermal headroom the device currently has
 * before hitting severe throttling.
 *
 * Note that this only attempts to track the headroom of slow-moving sensors,
 * such as the skin temperature sensor. This means that there is no benefit to
 * calling this function more frequently than about once per second, and attempts
 * to call significantly more frequently may result in the function returning {@code NaN}.
 *
 * See also PowerManager#getThermalHeadroom.
 *
 * @param manager The manager instance to use
 * @param forecastSeconds how many seconds in the future to forecast
 * @return a value greater than or equal to 0.0 where 1.0 indicates the SEVERE throttling
 *  	   threshold. Returns NaN if the device does not support this functionality or if
 * 	       this function is called significantly faster than once per second.
 */
float AThermal_getThermalHeadroom(AThermalManager *manager,
        int forecastSeconds) {
    float result = 0.0f;
    status_t ret = manager->getThermalHeadroom(forecastSeconds, &result);

    if (ret != OK) {
        result = std::numeric_limits<float>::quiet_NaN();
    }

    return result;
}
