/*
 * Copyright © 2023 UBports Foundation
 *
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 3,
 * as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Authored by: Alfred Neumayer <dev.beidl@gmail.com>
 */

#pragma once

#include "src/core/performance_booster.h"

#include <memory>
#include <string>
#include <thread>

#include <deviceinfo/deviceinfo.h>
#include <gbinder.h>

#define BINDER_UNISOC_SERVICE_IFACE "vendor.sprd.hardware.power@4.0::IPower"
#define BINDER_UNISOC_SERVICE_FQNAME BINDER_UNISOC_SERVICE_IFACE "/default"

namespace repowerd
{

class Log;

class BinderPerformanceBooster : public PerformanceBooster
{
public:
    BinderPerformanceBooster(std::shared_ptr<Log> const& log);
    ~BinderPerformanceBooster();

    void enable_interactive_mode() override;
    void disable_interactive_mode() override;

private:
    struct PowerHalInterface {
        std::string device;
        std::string interface;
        std::string fqname;
        std::string scene_interface;
        std::string scene_fqname;
        int scene_acquire_method;
        int scene_release_method;
    };

    enum HalPowerHint {
        INTERACTION = 0x00000002,
        LOW_POWER = 0x00000005,
        SUSTAINED_PERFORMANCE = 0x00000006
    };

    PowerHalInterface sprd_interface {
        "/dev/hwbinder",
        "android.hardware.power@1.0::IPower",
        "android.hardware.power@1.0::IPower/default",
        "vendor.sprd.hardware.power@4.0::IPower",
        "vendor.sprd.hardware.power@4.0::IPower/default",
        11,
        12
    };

    PowerHalInterface fallback_interface {
        "/dev/hwbinder",
        "android.hardware.power@1.0::IPower",
        "android.hardware.power@1.0::IPower/default",
        "",
        "",
        0,
        0
    };

    PowerHalInterface* active_interface;

    void set_interactive(const bool enable);
    void set_scenario(const HalPowerHint hint, const bool enable);
    void acquire_power_scene(const std::string& name);
    void release_power_scene(const std::string& name);

    std::string mSceneOnName;
    std::string mSceneOffName;

    std::shared_ptr<Log> const log;
    GBinderServiceManager *mSm;
    GBinderRemoteObject *mRemote;
    GBinderClient *mClient;
    GBinderRemoteObject *mSceneRemote;
    GBinderClient *mSceneClient;
};

}
