/*
 * 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.
 */
#include <aidl/Gtest.h>
#include <aidl/Vintf.h>

#include <aidl/android/hardware/power/BnPower.h>
#include <aidl/android/hardware/power/BnPowerHintSession.h>
#include <android-base/properties.h>
#include <android/binder_ibinder.h>
#include <android/binder_manager.h>
#include <android/binder_process.h>
#include <android/binder_status.h>

#include <fmq/AidlMessageQueue.h>
#include <fmq/EventFlag.h>

#include <unistd.h>
#include <cstdint>
#include "aidl/android/hardware/common/fmq/SynchronizedReadWrite.h"
#include "aidl/android/hardware/power/CpuHeadroomParams.h"
#include "aidl/android/hardware/power/GpuHeadroomParams.h"

namespace aidl::android::hardware::power {
namespace {

using namespace std::chrono_literals;

using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
using ::android::AidlMessageQueue;
using ::android::hardware::EventFlag;
using android::hardware::power::Boost;
using android::hardware::power::ChannelConfig;
using android::hardware::power::ChannelMessage;
using android::hardware::power::CpuHeadroomParams;
using android::hardware::power::CpuHeadroomResult;
using android::hardware::power::GpuHeadroomParams;
using android::hardware::power::GpuHeadroomResult;
using android::hardware::power::IPower;
using android::hardware::power::IPowerHintSession;
using android::hardware::power::Mode;
using android::hardware::power::SessionHint;
using android::hardware::power::SessionMode;
using android::hardware::power::SupportInfo;
using android::hardware::power::WorkDuration;
using ChannelMessageContents = ChannelMessage::ChannelMessageContents;
using ModeSetter = ChannelMessage::ChannelMessageContents::SessionModeSetter;
using MessageTag = ChannelMessage::ChannelMessageContents::Tag;

using SessionMessageQueue = AidlMessageQueue<ChannelMessage, SynchronizedReadWrite>;
using FlagMessageQueue = AidlMessageQueue<int8_t, SynchronizedReadWrite>;

const std::vector<Boost> kBoosts{ndk::enum_range<Boost>().begin(), ndk::enum_range<Boost>().end()};

const std::vector<Mode> kModes{ndk::enum_range<Mode>().begin(), ndk::enum_range<Mode>().end()};

const std::vector<SessionHint> kSessionHints{ndk::enum_range<SessionHint>().begin(),
                                             ndk::enum_range<SessionHint>().end()};

const std::vector<SessionMode> kSessionModes{ndk::enum_range<SessionMode>().begin(),
                                             ndk::enum_range<SessionMode>().end()};

const std::vector<Boost> kInvalidBoosts = {
        static_cast<Boost>(static_cast<int32_t>(kBoosts.front()) - 1),
        static_cast<Boost>(static_cast<int32_t>(kBoosts.back()) + 1),
};

const std::vector<Mode> kInvalidModes = {
        static_cast<Mode>(static_cast<int32_t>(kModes.front()) - 1),
        static_cast<Mode>(static_cast<int32_t>(kModes.back()) + 1),
};

const std::vector<SessionHint> kInvalidSessionHints = {
        static_cast<SessionHint>(static_cast<int32_t>(kSessionHints.front()) - 1),
        static_cast<SessionHint>(static_cast<int32_t>(kSessionHints.back()) + 1),
};

const std::vector<SessionMode> kInvalidSessionModes = {
        static_cast<SessionMode>(static_cast<int32_t>(kSessionModes.front()) - 1),
        static_cast<SessionMode>(static_cast<int32_t>(kSessionModes.back()) + 1),
};

template <class T>
constexpr size_t enum_size() {
    return static_cast<size_t>(*(ndk::enum_range<T>().end() - 1)) + 1;
}

template <class E>
bool supportFromBitset(int64_t& supportInt, E type) {
    return (supportInt >> static_cast<int>(type)) % 2;
}

class DurationWrapper : public WorkDuration {
  public:
    DurationWrapper(int64_t dur, int64_t time) {
        durationNanos = dur;
        timeStampNanos = time;
    }
};

const std::vector<int32_t> kSelfTids = {
        gettid(),
};

const std::vector<int32_t> kEmptyTids = {};

const std::vector<WorkDuration> kDurationsWithZero = {
        DurationWrapper(1000L, 1L),
        DurationWrapper(0L, 2L),
};

const std::vector<WorkDuration> kDurationsWithNegative = {
        DurationWrapper(1000L, 1L),
        DurationWrapper(-1000L, 2L),
};

const std::vector<WorkDuration> kDurations = {
        DurationWrapper(1L, 1L),
        DurationWrapper(1000L, 2L),
        DurationWrapper(1000000L, 3L),
        DurationWrapper(1000000000L, 4L),
};

class PowerAidl : public testing::TestWithParam<std::string> {
  public:
    virtual void SetUp() override {
        AIBinder* binder = AServiceManager_waitForService(GetParam().c_str());
        ASSERT_NE(binder, nullptr);
        power = IPower::fromBinder(ndk::SpAIBinder(binder));
        auto status = power->getInterfaceVersion(&mServiceVersion);
        ASSERT_TRUE(status.isOk());
        if (mServiceVersion >= 2) {
            status = power->createHintSession(getpid(), getuid(), kSelfTids, 16666666L, &mSession);
            mSessionSupport = status.isOk();
        }
        if (mServiceVersion >= 6) {
            mSupportInfo = std::make_optional<SupportInfo>();
            ASSERT_TRUE(power->getSupportInfo(&(*mSupportInfo)).isOk());
        }
    }

    std::shared_ptr<IPower> power;
    int32_t mServiceVersion;
    std::shared_ptr<IPowerHintSession> mSession;
    bool mSessionSupport = false;
    std::optional<SupportInfo> mSupportInfo = std::nullopt;
};

class HintSessionAidl : public PowerAidl {
  public:
    virtual void SetUp() override {
        PowerAidl::SetUp();
        if (mServiceVersion < 2) {
            GTEST_SKIP() << "DEVICE not launching with Power V2 and beyond.";
        }
        if (!mSessionSupport) {
            GTEST_SKIP() << "DEVICE not support Hint Session.";
        }
        ASSERT_NE(nullptr, mSession);
    }
};

class FMQAidl : public PowerAidl {
  public:
    virtual void SetUp() override {
        PowerAidl::SetUp();
        if (mServiceVersion < 5) {
            GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
        }

        auto status =
                power->createHintSessionWithConfig(getpid(), getuid(), kSelfTids, 16666666L,
                                                   SessionTag::OTHER, &mSessionConfig, &mSession);
        mSessionSupport = status.isOk();
        if (!mSessionSupport) {
            GTEST_SKIP() << "DEVICE not support Hint Session.";
        }
        ASSERT_NE(nullptr, mSession);

        status = power->getSessionChannel(getpid(), getuid(), &mChannelConfig);
        ASSERT_TRUE(status.isOk());
        mChannel = std::make_shared<SessionMessageQueue>(mChannelConfig.channelDescriptor, true);
        ASSERT_TRUE(mChannel->isValid());

        if (mChannelConfig.eventFlagDescriptor.has_value()) {
            mFlagChannel =
                    std::make_shared<FlagMessageQueue>(*mChannelConfig.eventFlagDescriptor, true);
            ASSERT_EQ(EventFlag::createEventFlag(mFlagChannel->getEventFlagWord(), &mEventFlag),
                      ::android::OK);
        } else {
            ASSERT_EQ(EventFlag::createEventFlag(mChannel->getEventFlagWord(), &mEventFlag),
                      ::android::OK);
        }

        ASSERT_NE(mEventFlag, nullptr);
    }
    virtual void TearDown() {
        if (mSession) {
            mSession->close();
            if (mChannel->isValid()) {
                ASSERT_TRUE(power->closeSessionChannel(getpid(), getuid()).isOk());
            }
        }
    }

  protected:
    std::shared_ptr<IPowerHintSession> mSession;
    std::shared_ptr<SessionMessageQueue> mChannel;
    std::shared_ptr<FlagMessageQueue> mFlagChannel;
    SessionConfig mSessionConfig;
    ChannelConfig mChannelConfig;
    ::android::hardware::EventFlag* mEventFlag;
};

TEST_P(PowerAidl, setMode) {
    for (const auto& mode : kModes) {
        ASSERT_TRUE(power->setMode(mode, true).isOk());
        ASSERT_TRUE(power->setMode(mode, false).isOk());
    }
    for (const auto& mode : kInvalidModes) {
        ASSERT_TRUE(power->setMode(mode, true).isOk());
        ASSERT_TRUE(power->setMode(mode, false).isOk());
    }
}

TEST_P(PowerAidl, isModeSupported) {
    for (const auto& mode : kModes) {
        bool supported;
        ASSERT_TRUE(power->isModeSupported(mode, &supported).isOk());
    }
    for (const auto& mode : kInvalidModes) {
        bool supported;
        ASSERT_TRUE(power->isModeSupported(mode, &supported).isOk());
        // Should return false for values outside enum
        ASSERT_FALSE(supported);
    }
}

TEST_P(PowerAidl, setBoost) {
    for (const auto& boost : kBoosts) {
        ASSERT_TRUE(power->setBoost(boost, 0).isOk());
        ASSERT_TRUE(power->setBoost(boost, 1000).isOk());
        ASSERT_TRUE(power->setBoost(boost, -1).isOk());
    }
    for (const auto& boost : kInvalidBoosts) {
        ASSERT_TRUE(power->setBoost(boost, 0).isOk());
        ASSERT_TRUE(power->setBoost(boost, 1000).isOk());
        ASSERT_TRUE(power->setBoost(boost, -1).isOk());
    }
}

TEST_P(PowerAidl, isBoostSupported) {
    for (const auto& boost : kBoosts) {
        bool supported;
        ASSERT_TRUE(power->isBoostSupported(boost, &supported).isOk());
    }
    for (const auto& boost : kInvalidBoosts) {
        bool supported;
        ASSERT_TRUE(power->isBoostSupported(boost, &supported).isOk());
        // Should return false for values outside enum
        ASSERT_FALSE(supported);
    }
}

TEST_P(PowerAidl, getHintSessionPreferredRate) {
    if (!mSessionSupport) {
        GTEST_SKIP() << "DEVICE not support Hint Session.";
    }
    if (mServiceVersion < 2) {
        GTEST_SKIP() << "DEVICE not launching with Power V2 and beyond.";
    }

    int64_t rate = -1;
    ASSERT_TRUE(power->getHintSessionPreferredRate(&rate).isOk());
    // At least 1ms rate limit from HAL
    ASSERT_GE(rate, 1000000);
}

TEST_P(PowerAidl, createHintSessionWithConfig) {
    if (!mSessionSupport) {
        GTEST_SKIP() << "DEVICE not support Hint Session.";
    }
    if (mServiceVersion < 5) {
        GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
    }
    std::shared_ptr<IPowerHintSession> session;
    SessionConfig config;

    auto status = power->createHintSessionWithConfig(getpid(), getuid(), kSelfTids, 16666666L,
                                                     SessionTag::OTHER, &config, &session);
    ASSERT_TRUE(status.isOk());
    ASSERT_NE(nullptr, session);
}

TEST_P(PowerAidl, getCpuHeadroom) {
    if (mServiceVersion < 6) {
        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
    }
    CpuHeadroomParams params;
    CpuHeadroomResult headroom;
    auto ret = power->getCpuHeadroom(params, &headroom);
    if (!mSupportInfo->headroom.isCpuSupported) {
        ASSERT_EQ(ret.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
        GTEST_SKIP() << "power->getCpuHeadroom is not supported";
    }
    ASSERT_TRUE(ret.isOk());
    ASSERT_GE(mSupportInfo->headroom.cpuMinIntervalMillis, 0);
    ASSERT_EQ(headroom.getTag(), CpuHeadroomResult::globalHeadroom);
    ASSERT_GE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 0.0f);
    ASSERT_LE(headroom.get<CpuHeadroomResult::globalHeadroom>(), 100.00f);
}

TEST_P(PowerAidl, getGpuHeadroom) {
    if (mServiceVersion < 6) {
        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
    }
    GpuHeadroomParams params;
    GpuHeadroomResult headroom;
    auto ret = power->getGpuHeadroom(params, &headroom);
    if (!mSupportInfo->headroom.isGpuSupported) {
        ASSERT_EQ(ret.getExceptionCode(), EX_UNSUPPORTED_OPERATION);
        GTEST_SKIP() << "power->getGpuHeadroom is not supported";
    }
    ASSERT_TRUE(ret.isOk());
    ASSERT_GE(mSupportInfo->headroom.gpuMinIntervalMillis, 0);
    ASSERT_EQ(headroom.getTag(), GpuHeadroomResult::globalHeadroom);
    ASSERT_GE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 0.0f);
    ASSERT_LE(headroom.get<GpuHeadroomResult::globalHeadroom>(), 100.00f);
}

// FIXED_PERFORMANCE mode is required for all devices which ship on Android 11
// or later
TEST_P(PowerAidl, hasFixedPerformance) {
    bool supported;
    ASSERT_TRUE(power->isModeSupported(Mode::FIXED_PERFORMANCE, &supported).isOk());
    ASSERT_TRUE(supported);
}

TEST_P(PowerAidl, hasSupportInfo) {
    if (mServiceVersion < 6) {
        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
    }
    ASSERT_TRUE(mSupportInfo.has_value());
    for (Mode mode : kModes) {
        bool supported;
        power->isModeSupported(mode, &supported);
        ASSERT_EQ(supported, supportFromBitset(mSupportInfo->modes, mode));
    }
    for (Boost boost : kBoosts) {
        bool supported;
        power->isBoostSupported(boost, &supported);
        ASSERT_EQ(supported, supportFromBitset(mSupportInfo->boosts, boost));
    }
}

TEST_P(PowerAidl, receivesCompositionData) {
    if (mServiceVersion < 6) {
        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
    }
    if (mSupportInfo->compositionData.isSupported) {
        GTEST_SKIP() << "Composition data marked as unsupported.";
    }
    // Sending an empty object is fine, we just want to confirm it accepts the tx
    std::vector<CompositionData> out{};
    out.emplace_back();
    auto status = power->sendCompositionData(out);
    ASSERT_TRUE(status.isOk());
}

TEST_P(PowerAidl, receivesCompositionUpdate) {
    if (mServiceVersion < 6) {
        GTEST_SKIP() << "DEVICE not launching with Power V6 and beyond.";
    }
    if (mSupportInfo->compositionData.isSupported) {
        GTEST_SKIP() << "Composition data marked as unsupported.";
    }

    CompositionUpdate out{};
    auto status = power->sendCompositionUpdate(out);
    ASSERT_TRUE(status.isOk());
}

TEST_P(HintSessionAidl, createAndCloseHintSession) {
    if (!mSessionSupport) {
        GTEST_SKIP() << "DEVICE not support Hint Session.";
    }
    ASSERT_TRUE(mSession->pause().isOk());
    ASSERT_TRUE(mSession->resume().isOk());
    // Test normal destroy operation
    ASSERT_TRUE(mSession->close().isOk());
    mSession.reset();
}

TEST_P(HintSessionAidl, createHintSessionFailed) {
    if (!mSessionSupport) {
        GTEST_SKIP() << "DEVICE not support Hint Session.";
    }
    std::shared_ptr<IPowerHintSession> session;
    auto status = power->createHintSession(getpid(), getuid(), kEmptyTids, 16666666L, &session);

    // Regardless of whether V2 and beyond is supported, the status is always not STATUS_OK.
    ASSERT_FALSE(status.isOk());
    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());
}

TEST_P(HintSessionAidl, updateAndReportDurations) {
    if (!mSessionSupport) {
        GTEST_SKIP() << "DEVICE not support Hint Session.";
    }
    ASSERT_TRUE(mSession->updateTargetWorkDuration(16666667LL).isOk());
    ASSERT_TRUE(mSession->reportActualWorkDuration(kDurations).isOk());
}

TEST_P(HintSessionAidl, sendSessionHint) {
    if (!mSessionSupport) {
        GTEST_SKIP() << "DEVICE not support Hint Session.";
    }
    if (mServiceVersion < 4) {
        GTEST_SKIP() << "DEVICE not launching with Power V4 and beyond.";
    }

    for (const auto& sessionHint : kSessionHints) {
        ASSERT_TRUE(mSession->sendHint(sessionHint).isOk());
    }
    for (const auto& sessionHint : kInvalidSessionHints) {
        ASSERT_TRUE(mSession->sendHint(sessionHint).isOk());
    }
}

TEST_P(HintSessionAidl, setThreads) {
    if (!mSessionSupport) {
        GTEST_SKIP() << "DEVICE not support Hint Session.";
    }
    if (mServiceVersion < 4) {
        GTEST_SKIP() << "DEVICE not launching with Power V4 and beyond.";
    }

    auto status = mSession->setThreads(kEmptyTids);
    ASSERT_FALSE(status.isOk());
    ASSERT_EQ(EX_ILLEGAL_ARGUMENT, status.getExceptionCode());

    ASSERT_TRUE(mSession->setThreads(kSelfTids).isOk());
}

TEST_P(HintSessionAidl, setSessionMode) {
    if (!mSessionSupport) {
        GTEST_SKIP() << "DEVICE not support Hint Session.";
    }
    if (mServiceVersion < 5) {
        GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
    }

    for (const auto& sessionMode : kSessionModes) {
        ASSERT_TRUE(mSession->setMode(sessionMode, true).isOk());
        ASSERT_TRUE(mSession->setMode(sessionMode, false).isOk());
    }
    for (const auto& sessionMode : kInvalidSessionModes) {
        ASSERT_TRUE(mSession->setMode(sessionMode, true).isOk());
        ASSERT_TRUE(mSession->setMode(sessionMode, false).isOk());
    }
}

TEST_P(HintSessionAidl, getSessionConfig) {
    if (!mSessionSupport) {
        GTEST_SKIP() << "DEVICE not support Hint Session.";
    }
    if (mServiceVersion < 5) {
        GTEST_SKIP() << "DEVICE not launching with Power V5 and beyond.";
    }
    SessionConfig config;
    ASSERT_TRUE(mSession->getSessionConfig(&config).isOk());
}

TEST_P(FMQAidl, getAndCloseSessionChannel) {}

TEST_P(FMQAidl, writeItems) {
    std::vector<ChannelMessage> messages{
            {.sessionID = static_cast<int32_t>(mSessionConfig.id),
             .timeStampNanos = 1000,
             .data = ChannelMessageContents::make<MessageTag::workDuration, WorkDurationFixedV1>(
                     {.durationNanos = 1000,
                      .workPeriodStartTimestampNanos = 10,
                      .cpuDurationNanos = 900,
                      .gpuDurationNanos = 100})},
            {.sessionID = static_cast<int32_t>(mSessionConfig.id),
             .timeStampNanos = 1000,
             .data = ChannelMessageContents::make<MessageTag::mode, ModeSetter>(
                     {.modeInt = SessionMode::POWER_EFFICIENCY, .enabled = true})},
            {.sessionID = static_cast<int32_t>(mSessionConfig.id),
             .timeStampNanos = 1000,
             .data = ChannelMessageContents::make<MessageTag::hint, SessionHint>(
                     SessionHint::CPU_LOAD_UP)},
            {.sessionID = static_cast<int32_t>(mSessionConfig.id),
             .timeStampNanos = 1000,
             .data = ChannelMessageContents::make<MessageTag::targetDuration, int64_t>(
                     10000000 /* 10ms */)},
    };
    for (auto& message : messages) {
        ASSERT_TRUE(mChannel->writeBlocking(&message, 1, mChannelConfig.readFlagBitmask,
                                            mChannelConfig.writeFlagBitmask, 100000000,
                                            mEventFlag));
    }
    // Make sure this still works after everything else is done to check crash
    ASSERT_TRUE(mSession->setThreads(kSelfTids).isOk());
}

TEST_P(FMQAidl, writeExcess) {
    std::vector<ChannelMessage> messages;
    size_t channelSize = mChannel->getQuantumCount();
    for (size_t i = 0; i < channelSize; ++i) {
        messages.push_back({.sessionID = static_cast<int32_t>(mSessionConfig.id),
                            .timeStampNanos = 1000,
                            .data = ChannelMessageContents::make<MessageTag::hint, SessionHint>(
                                    SessionHint::CPU_LOAD_UP)});
    }
    ASSERT_TRUE(mChannel->writeBlocking(messages.data(), messages.size(),
                                        mChannelConfig.readFlagBitmask,
                                        mChannelConfig.writeFlagBitmask, 100000000, mEventFlag));
    ASSERT_TRUE(mChannel->writeBlocking(messages.data(), messages.size(),
                                        mChannelConfig.readFlagBitmask,
                                        mChannelConfig.writeFlagBitmask, 1000000000, mEventFlag));
    // Make sure this still works after everything else is done to check crash
    ASSERT_TRUE(mSession->setThreads(kSelfTids).isOk());
}

GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(PowerAidl);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(HintSessionAidl);
GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(FMQAidl);

INSTANTIATE_TEST_SUITE_P(Power, PowerAidl,
                         testing::ValuesIn(::android::getAidlHalInstanceNames(IPower::descriptor)),
                         ::android::PrintInstanceNameToString);
INSTANTIATE_TEST_SUITE_P(Power, HintSessionAidl,
                         testing::ValuesIn(::android::getAidlHalInstanceNames(IPower::descriptor)),
                         ::android::PrintInstanceNameToString);
INSTANTIATE_TEST_SUITE_P(Power, FMQAidl,
                         testing::ValuesIn(::android::getAidlHalInstanceNames(IPower::descriptor)),
                         ::android::PrintInstanceNameToString);

}  // namespace
}  // namespace aidl::android::hardware::power

int main(int argc, char** argv) {
    ::testing::InitGoogleTest(&argc, argv);
    ABinderProcess_setThreadPoolMaxThreadCount(1);
    ABinderProcess_startThreadPool();
    return RUN_ALL_TESTS();
}
