/*
 * Copyright (C) 2022 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/android/hardware/vibrator/BnVibratorCallback.h>
#include <android-base/logging.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include <linux/input.h>
#include <linux/uinput.h>

#include <future>

#include "Vibrator.h"
#include "mocks.h"
#include "types.h"
#include "utils.h"

namespace aidl {
namespace android {
namespace hardware {
namespace vibrator {

using ::testing::_;
using ::testing::AnyNumber;
using ::testing::Assign;
using ::testing::AtLeast;
using ::testing::AtMost;
using ::testing::Combine;
using ::testing::DoAll;
using ::testing::DoDefault;
using ::testing::Exactly;
using ::testing::Expectation;
using ::testing::ExpectationSet;
using ::testing::Ge;
using ::testing::Mock;
using ::testing::MockFunction;
using ::testing::Range;
using ::testing::Return;
using ::testing::Sequence;
using ::testing::SetArgPointee;
using ::testing::SetArgReferee;
using ::testing::Test;
using ::testing::TestParamInfo;
using ::testing::ValuesIn;
using ::testing::WithParamInterface;

// Forward Declarations

static EffectQueue Queue(const QueueEffect &effect);
static EffectQueue Queue(const QueueDelay &delay);
template <typename T, typename U, typename... Args>
static EffectQueue Queue(const T &first, const U &second, Args... rest);

static EffectLevel Level(float intensity, float levelLow, float levelHigh);
static EffectScale Scale(float intensity, float levelLow, float levelHigh);

// Constants With Arbitrary Values

static constexpr uint32_t CAL_VERSION = 2;
static constexpr std::array<EffectLevel, 2> V_TICK_DEFAULT = {1, 100};
static constexpr std::array<EffectLevel, 2> V_CLICK_DEFAULT{1, 100};
static constexpr std::array<EffectLevel, 2> V_LONG_DEFAULT{1, 100};
static constexpr std::array<EffectDuration, 14> EFFECT_DURATIONS{
        0, 100, 30, 1000, 300, 130, 150, 500, 100, 15, 20, 1000, 1000, 1000};

// Constants With Prescribed Values

static const std::map<Effect, EffectIndex> EFFECT_INDEX{
        {Effect::CLICK, 2},
        {Effect::TICK, 2},
        {Effect::HEAVY_CLICK, 2},
        {Effect::TEXTURE_TICK, 9},
};
static constexpr uint32_t MIN_ON_OFF_INTERVAL_US = 8500;
static constexpr uint8_t VOLTAGE_SCALE_MAX = 100;
static constexpr int8_t MAX_COLD_START_LATENCY_MS = 6;  // I2C Transaction + DSP Return-From-Standby
static constexpr auto POLLING_TIMEOUT = 20;
enum WaveformIndex : uint16_t {
    /* Physical waveform */
    WAVEFORM_LONG_VIBRATION_EFFECT_INDEX = 0,
    WAVEFORM_RESERVED_INDEX_1 = 1,
    WAVEFORM_CLICK_INDEX = 2,
    WAVEFORM_SHORT_VIBRATION_EFFECT_INDEX = 3,
    WAVEFORM_THUD_INDEX = 4,
    WAVEFORM_SPIN_INDEX = 5,
    WAVEFORM_QUICK_RISE_INDEX = 6,
    WAVEFORM_SLOW_RISE_INDEX = 7,
    WAVEFORM_QUICK_FALL_INDEX = 8,
    WAVEFORM_LIGHT_TICK_INDEX = 9,
    WAVEFORM_LOW_TICK_INDEX = 10,
    WAVEFORM_RESERVED_MFG_1,
    WAVEFORM_RESERVED_MFG_2,
    WAVEFORM_RESERVED_MFG_3,
    WAVEFORM_MAX_PHYSICAL_INDEX,
    /* OWT waveform */
    WAVEFORM_COMPOSE = WAVEFORM_MAX_PHYSICAL_INDEX,
    WAVEFORM_PWLE,
    /*
     * Refer to <linux/input.h>, the WAVEFORM_MAX_INDEX must not exceed 96.
     * #define FF_GAIN          0x60  // 96 in decimal
     * #define FF_MAX_EFFECTS   FF_GAIN
     */
    WAVEFORM_MAX_INDEX,
};

static const EffectScale ON_GLOBAL_SCALE{levelToScale(V_LONG_DEFAULT[1])};
static const EffectIndex ON_EFFECT_INDEX{0};

static const std::map<EffectTuple, EffectScale> EFFECT_SCALE{
        {{Effect::TICK, EffectStrength::LIGHT},
         Scale(0.5f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
        {{Effect::TICK, EffectStrength::MEDIUM},
         Scale(0.5f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
        {{Effect::TICK, EffectStrength::STRONG},
         Scale(0.5f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
        {{Effect::CLICK, EffectStrength::LIGHT},
         Scale(0.7f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
        {{Effect::CLICK, EffectStrength::MEDIUM},
         Scale(0.7f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
        {{Effect::CLICK, EffectStrength::STRONG},
         Scale(0.7f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
        {{Effect::HEAVY_CLICK, EffectStrength::LIGHT},
         Scale(1.0f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
        {{Effect::HEAVY_CLICK, EffectStrength::MEDIUM},
         Scale(1.0f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
        {{Effect::HEAVY_CLICK, EffectStrength::STRONG},
         Scale(1.0f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
        {{Effect::TEXTURE_TICK, EffectStrength::LIGHT},
         Scale(0.5f * 0.5f, V_TICK_DEFAULT[0], V_TICK_DEFAULT[1])},
        {{Effect::TEXTURE_TICK, EffectStrength::MEDIUM},
         Scale(0.5f * 0.7f, V_TICK_DEFAULT[0], V_TICK_DEFAULT[1])},
        {{Effect::TEXTURE_TICK, EffectStrength::STRONG},
         Scale(0.5f * 1.0f, V_TICK_DEFAULT[0], V_TICK_DEFAULT[1])},
};

static const std::map<EffectTuple, EffectQueue> EFFECT_QUEUE{
        {{Effect::DOUBLE_CLICK, EffectStrength::LIGHT},
         Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
                           Level(0.7f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
               100,
               QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
                           Level(1.0f * 0.5f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])})},
        {{Effect::DOUBLE_CLICK, EffectStrength::MEDIUM},
         Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
                           Level(0.7f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
               100,
               QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
                           Level(1.0f * 0.7f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])})},
        {{Effect::DOUBLE_CLICK, EffectStrength::STRONG},
         Queue(QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
                           Level(0.7f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])},
               100,
               QueueEffect{EFFECT_INDEX.at(Effect::CLICK),
                           Level(1.0f * 1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])})},
};

EffectQueue Queue(const QueueEffect &effect) {
    auto index = std::get<0>(effect);
    auto level = std::get<1>(effect);
    auto string = std::to_string(index) + "." + std::to_string(level);
    auto duration = EFFECT_DURATIONS[index];
    return {string, duration};
}

EffectQueue Queue(const QueueDelay &delay) {
    auto string = std::to_string(delay);
    return {string, delay};
}

template <typename T, typename U, typename... Args>
EffectQueue Queue(const T &first, const U &second, Args... rest) {
    auto head = Queue(first);
    auto tail = Queue(second, rest...);
    auto string = std::get<0>(head) + "," + std::get<0>(tail);
    auto duration = std::get<1>(head) + std::get<1>(tail);
    return {string, duration};
}

static EffectLevel Level(float intensity, float levelLow, float levelHigh) {
    return std::lround(intensity * (levelHigh - levelLow)) + levelLow;
}

static EffectScale Scale(float intensity, float levelLow, float levelHigh) {
    return levelToScale(Level(intensity, levelLow, levelHigh));
}

class VibratorTest : public Test {
  public:
    void SetUp() override {
        setenv("INPUT_EVENT_NAME", "CS40L26TestSuite", true);
        std::unique_ptr<MockApi> mockapi;
        std::unique_ptr<MockCal> mockcal;
        std::unique_ptr<MockGPIO> mockgpio;

        createMock(&mockapi, &mockcal, &mockgpio);
        createVibrator(std::move(mockapi), std::move(mockcal), std::move(mockgpio));
    }

    void TearDown() override { deleteVibrator(); }

  protected:
    void createMock(std::unique_ptr<MockApi> *mockapi, std::unique_ptr<MockCal> *mockcal,
                    std::unique_ptr<MockGPIO> *mockgpio) {
        *mockapi = std::make_unique<MockApi>();
        *mockcal = std::make_unique<MockCal>();
        *mockgpio = std::make_unique<MockGPIO>();

        mMockApi = mockapi->get();
        mMockCal = mockcal->get();
        mMockGpio = mockgpio->get();

        ON_CALL(*mMockApi, destructor()).WillByDefault(Assign(&mMockApi, nullptr));

        ON_CALL(*mMockApi, setFFGain(_, _)).WillByDefault(Return(true));
        ON_CALL(*mMockApi, setFFEffect(_, _, _)).WillByDefault(Return(true));
        ON_CALL(*mMockApi, setFFPlay(_, _, _)).WillByDefault(Return(true));
        ON_CALL(*mMockApi, pollVibeState(_, _)).WillByDefault(Return(true));
        ON_CALL(*mMockApi, uploadOwtEffect(_, _, _, _, _, _)).WillByDefault(Return(true));
        ON_CALL(*mMockApi, eraseOwtEffect(_, _, _)).WillByDefault(Return(true));

        ON_CALL(*mMockApi, getOwtFreeSpace(_))
                .WillByDefault(DoAll(SetArgPointee<0>(11504), Return(true)));

        ON_CALL(*mMockCal, destructor()).WillByDefault(Assign(&mMockCal, nullptr));

        ON_CALL(*mMockCal, getVersion(_))
                .WillByDefault(DoAll(SetArgPointee<0>(CAL_VERSION), Return(true)));

        ON_CALL(*mMockCal, getTickVolLevels(_))
                .WillByDefault(DoAll(SetArgPointee<0>(V_TICK_DEFAULT), Return(true)));
        ON_CALL(*mMockCal, getClickVolLevels(_))
                .WillByDefault(DoAll(SetArgPointee<0>(V_CLICK_DEFAULT), Return(true)));
        ON_CALL(*mMockCal, getLongVolLevels(_))
                .WillByDefault(DoAll(SetArgPointee<0>(V_LONG_DEFAULT), Return(true)));

        ON_CALL(*mMockGpio, destructor()).WillByDefault(Assign(&mMockGpio, nullptr));

        relaxMock(false);
    }

    void createVibrator(std::unique_ptr<MockApi> mockapi, std::unique_ptr<MockCal> mockcal,
                        std::unique_ptr<MockGPIO> mockgpio, bool relaxed = true) {
        if (relaxed) {
            relaxMock(true);
        }
        // TODO(b/261415845): Need to add dual parameters to test the vibrator HAL's code in haptics
        // mock test
        mVibrator = ndk::SharedRefBase::make<Vibrator>(std::move(mockapi), std::move(mockcal),
                                                       nullptr, nullptr, std::move(mockgpio));
        if (relaxed) {
            relaxMock(false);
        }
    }

    void deleteVibrator(bool relaxed = true) {
        if (relaxed) {
            relaxMock(true);
        }
        mVibrator.reset();
    }

  private:
    void relaxMock(bool relax) {
        auto times = relax ? AnyNumber() : Exactly(0);

        Mock::VerifyAndClearExpectations(mMockApi);
        Mock::VerifyAndClearExpectations(mMockCal);

        EXPECT_CALL(*mMockApi, destructor()).Times(times);
        EXPECT_CALL(*mMockApi, setF0(_)).Times(times);
        EXPECT_CALL(*mMockApi, setF0Offset(_)).Times(times);
        EXPECT_CALL(*mMockApi, setRedc(_)).Times(times);
        EXPECT_CALL(*mMockApi, setQ(_)).Times(times);
        EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).Times(times);
        EXPECT_CALL(*mMockApi, getOwtFreeSpace(_)).Times(times);
        EXPECT_CALL(*mMockApi, setF0CompEnable(_)).Times(times);
        EXPECT_CALL(*mMockApi, setRedcCompEnable(_)).Times(times);
        EXPECT_CALL(*mMockApi, pollVibeState(_, _)).Times(times);
        EXPECT_CALL(*mMockApi, setFFGain(_, _)).Times(times);
        EXPECT_CALL(*mMockApi, setFFEffect(_, _, _)).Times(times);
        EXPECT_CALL(*mMockApi, setFFPlay(_, _, _)).Times(times);
        EXPECT_CALL(*mMockApi, setMinOnOffInterval(_)).Times(times);
        EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).Times(times);
        EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, _, _, _)).Times(times);

        EXPECT_CALL(*mMockApi, debug(_)).Times(times);

        EXPECT_CALL(*mMockCal, destructor()).Times(times);
        EXPECT_CALL(*mMockCal, getF0(_)).Times(times);
        EXPECT_CALL(*mMockCal, getRedc(_)).Times(times);
        EXPECT_CALL(*mMockCal, getQ(_)).Times(times);
        EXPECT_CALL(*mMockCal, getTickVolLevels(_)).Times(times);
        EXPECT_CALL(*mMockCal, getClickVolLevels(_)).Times(times);
        EXPECT_CALL(*mMockCal, getLongVolLevels(_)).Times(times);
        EXPECT_CALL(*mMockCal, isChirpEnabled()).Times(times);
        EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).Times(times);
        EXPECT_CALL(*mMockCal, isF0CompEnabled()).Times(times);
        EXPECT_CALL(*mMockCal, isRedcCompEnabled()).Times(times);
        EXPECT_CALL(*mMockCal, debug(_)).Times(times);
    }

  protected:
    MockApi *mMockApi;
    MockCal *mMockCal;
    MockGPIO *mMockGpio;
    std::shared_ptr<IVibrator> mVibrator;
    uint32_t mEffectIndex;
};

TEST_F(VibratorTest, Constructor) {
    std::unique_ptr<MockApi> mockapi;
    std::unique_ptr<MockCal> mockcal;
    std::unique_ptr<MockGPIO> mockgpio;
    std::string f0Val = std::to_string(std::rand());
    std::string redcVal = std::to_string(std::rand());
    std::string qVal = std::to_string(std::rand());
    uint32_t calVer;
    uint32_t supportedPrimitivesBits = 0x0;
    Expectation volGet;
    Sequence f0Seq, redcSeq, qSeq, supportedPrimitivesSeq;

    EXPECT_CALL(*mMockApi, destructor()).WillOnce(DoDefault());
    EXPECT_CALL(*mMockCal, destructor()).WillOnce(DoDefault());
    EXPECT_CALL(*mMockGpio, destructor()).WillOnce(DoDefault());

    deleteVibrator(false);

    createMock(&mockapi, &mockcal, &mockgpio);

    EXPECT_CALL(*mMockCal, getF0(_))
            .InSequence(f0Seq)
            .WillOnce(DoAll(SetArgReferee<0>(f0Val), Return(true)));
    EXPECT_CALL(*mMockApi, setF0(f0Val)).InSequence(f0Seq).WillOnce(Return(true));

    EXPECT_CALL(*mMockCal, getRedc(_))
            .InSequence(redcSeq)
            .WillOnce(DoAll(SetArgReferee<0>(redcVal), Return(true)));
    EXPECT_CALL(*mMockApi, setRedc(redcVal)).InSequence(redcSeq).WillOnce(Return(true));

    EXPECT_CALL(*mMockCal, getQ(_))
            .InSequence(qSeq)
            .WillOnce(DoAll(SetArgReferee<0>(qVal), Return(true)));
    EXPECT_CALL(*mMockApi, setQ(qVal)).InSequence(qSeq).WillOnce(Return(true));

    EXPECT_CALL(*mMockCal, getLongFrequencyShift(_)).WillOnce(Return(true));

    mMockCal->getVersion(&calVer);
    if (calVer == 2) {
        volGet = EXPECT_CALL(*mMockCal, getTickVolLevels(_)).WillOnce(DoDefault());
        volGet = EXPECT_CALL(*mMockCal, getClickVolLevels(_)).WillOnce(DoDefault());
        volGet = EXPECT_CALL(*mMockCal, getLongVolLevels(_)).WillOnce(DoDefault());
    }

    EXPECT_CALL(*mMockCal, isF0CompEnabled()).WillOnce(Return(true));
    EXPECT_CALL(*mMockApi, setF0CompEnable(true)).WillOnce(Return(true));
    EXPECT_CALL(*mMockCal, isRedcCompEnabled()).WillOnce(Return(true));
    EXPECT_CALL(*mMockApi, setRedcCompEnable(true)).WillOnce(Return(true));

    EXPECT_CALL(*mMockCal, isChirpEnabled()).WillOnce(Return(true));
    EXPECT_CALL(*mMockCal, getSupportedPrimitives(_))
            .InSequence(supportedPrimitivesSeq)
            .WillOnce(DoAll(SetArgPointee<0>(supportedPrimitivesBits), Return(true)));

    EXPECT_CALL(*mMockApi, setMinOnOffInterval(MIN_ON_OFF_INTERVAL_US)).WillOnce(Return(true));
    createVibrator(std::move(mockapi), std::move(mockcal), std::move(mockgpio), false);
}

TEST_F(VibratorTest, on) {
    Sequence s1, s2;
    uint16_t duration = std::rand() + 1;

    EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
    EXPECT_CALL(*mMockApi, setFFEffect(_, _, duration + MAX_COLD_START_LATENCY_MS))
            .InSequence(s2)
            .WillOnce(DoDefault());
    EXPECT_CALL(*mMockApi, setFFPlay(_, ON_EFFECT_INDEX, true))
            .InSequence(s1, s2)
            .WillOnce(DoDefault());
    EXPECT_TRUE(mVibrator->on(duration, nullptr).isOk());
}

TEST_F(VibratorTest, off) {
    Sequence s1;
    EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
    EXPECT_TRUE(mVibrator->off().isOk());
}

TEST_F(VibratorTest, supportsAmplitudeControl_supported) {
    int32_t capabilities;
    EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
    EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));

    EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
    EXPECT_GT(capabilities & IVibrator::CAP_AMPLITUDE_CONTROL, 0);
}

TEST_F(VibratorTest, supportsExternalAmplitudeControl_unsupported) {
    int32_t capabilities;
    EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
    EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));

    EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
    EXPECT_EQ(capabilities & IVibrator::CAP_EXTERNAL_AMPLITUDE_CONTROL, 0);
}

TEST_F(VibratorTest, setAmplitude_supported) {
    EffectAmplitude amplitude = static_cast<float>(std::rand()) / RAND_MAX ?: 1.0f;

    EXPECT_CALL(*mMockApi, setFFGain(_, amplitudeToScale(amplitude))).WillOnce(Return(true));

    EXPECT_TRUE(mVibrator->setAmplitude(amplitude).isOk());
}

TEST_F(VibratorTest, supportsExternalControl_supported) {
    int32_t capabilities;
    EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
    EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(true));

    EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
    EXPECT_GT(capabilities & IVibrator::CAP_EXTERNAL_CONTROL, 0);
}

TEST_F(VibratorTest, supportsExternalControl_unsupported) {
    int32_t capabilities;
    EXPECT_CALL(*mMockApi, hasOwtFreeSpace()).WillOnce(Return(true));
    EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).WillOnce(Return(false));

    EXPECT_TRUE(mVibrator->getCapabilities(&capabilities).isOk());
    EXPECT_EQ(capabilities & IVibrator::CAP_EXTERNAL_CONTROL, 0);
}

TEST_F(VibratorTest, setExternalControl_enable) {
    Sequence s1, s2;
    EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE)).InSequence(s1).WillOnce(DoDefault());
    EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).InSequence(s2).WillOnce(Return(true));
    EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, true, _, _))
            .InSequence(s1, s2)
            .WillOnce(Return(true));

    EXPECT_TRUE(mVibrator->setExternalControl(true).isOk());
}

TEST_F(VibratorTest, setExternalControl_disable) {
    Sequence s1, s2, s3, s4;

    // The default mIsUnderExternalControl is false, so it needs to turn on the External Control
    // to make mIsUnderExternalControl become true.
    EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE))
            .InSequence(s1)
            .InSequence(s1)
            .WillOnce(DoDefault());
    EXPECT_CALL(*mMockApi, getHapticAlsaDevice(_, _)).InSequence(s2).WillOnce(Return(true));
    EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, true, _, _)).InSequence(s3).WillOnce(Return(true));

    EXPECT_TRUE(mVibrator->setExternalControl(true).isOk());

    EXPECT_CALL(*mMockApi, setFFGain(_, levelToScale(VOLTAGE_SCALE_MAX)))
            .InSequence(s4)
            .WillOnce(DoDefault());
    EXPECT_CALL(*mMockApi, setHapticPcmAmp(_, false, _, _))
            .InSequence(s1, s2, s3, s4)
            .WillOnce(Return(true));

    EXPECT_TRUE(mVibrator->setExternalControl(false).isOk());
}

class EffectsTest : public VibratorTest, public WithParamInterface<EffectTuple> {
  public:
    static auto PrintParam(const TestParamInfo<ParamType> &info) {
        auto param = info.param;
        auto effect = std::get<0>(param);
        auto strength = std::get<1>(param);
        return toString(effect) + "_" + toString(strength);
    }
};

TEST_P(EffectsTest, perform) {
    auto param = GetParam();
    auto effect = std::get<0>(param);
    auto strength = std::get<1>(param);
    auto scale = EFFECT_SCALE.find(param);
    auto queue = EFFECT_QUEUE.find(param);
    EffectDuration duration;
    auto callback = ndk::SharedRefBase::make<MockVibratorCallback>();
    std::promise<void> promise;
    std::future<void> future{promise.get_future()};
    auto complete = [&promise] {
        promise.set_value();
        return ndk::ScopedAStatus::ok();
    };
    bool composeEffect;

    ExpectationSet eSetup;
    Expectation eActivate, ePollHaptics, ePollStop, eEraseDone;

    if (scale != EFFECT_SCALE.end()) {
        EffectIndex index = EFFECT_INDEX.at(effect);
        duration = EFFECT_DURATIONS[index];

        eSetup += EXPECT_CALL(*mMockApi, setFFGain(_, levelToScale(scale->second)))
                          .WillOnce(DoDefault());
        eActivate = EXPECT_CALL(*mMockApi, setFFPlay(_, index, true))
                            .After(eSetup)
                            .WillOnce(DoDefault());
    } else if (queue != EFFECT_QUEUE.end()) {
        duration = std::get<1>(queue->second);
        eSetup += EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE))
                          .After(eSetup)
                          .WillOnce(DoDefault());
        eSetup += EXPECT_CALL(*mMockApi, getOwtFreeSpace(_)).WillOnce(DoDefault());
        eSetup += EXPECT_CALL(*mMockApi, uploadOwtEffect(_, _, _, _, _, _))
                          .After(eSetup)
                          .WillOnce(DoDefault());
        eActivate = EXPECT_CALL(*mMockApi, setFFPlay(_, WAVEFORM_COMPOSE, true))
                            .After(eSetup)
                            .WillOnce(DoDefault());
        composeEffect = true;
    } else {
        duration = 0;
    }

    if (duration) {
        ePollHaptics = EXPECT_CALL(*mMockApi, pollVibeState(1, POLLING_TIMEOUT))
                               .After(eActivate)
                               .WillOnce(DoDefault());
        ePollStop = EXPECT_CALL(*mMockApi, pollVibeState(0, -1))
                            .After(ePollHaptics)
                            .WillOnce(DoDefault());
        if (composeEffect) {
            eEraseDone = EXPECT_CALL(*mMockApi, eraseOwtEffect(_, _, _))
                                 .After(ePollStop)
                                 .WillOnce(DoDefault());
            EXPECT_CALL(*callback, onComplete()).After(eEraseDone).WillOnce(complete);
        } else {
            EXPECT_CALL(*callback, onComplete()).After(ePollStop).WillOnce(complete);
        }
    }

    int32_t lengthMs;
    ndk::ScopedAStatus status = mVibrator->perform(effect, strength, callback, &lengthMs);
    if (status.isOk()) {
        EXPECT_LE(duration, lengthMs);
    } else {
        EXPECT_EQ(EX_UNSUPPORTED_OPERATION, status.getExceptionCode());
        EXPECT_EQ(0, lengthMs);
    }

    if (duration) {
        EXPECT_EQ(future.wait_for(std::chrono::milliseconds(100)), std::future_status::ready);
    }
}

const std::vector<Effect> kEffects{ndk::enum_range<Effect>().begin(),
                                   ndk::enum_range<Effect>().end()};
const std::vector<EffectStrength> kEffectStrengths{ndk::enum_range<EffectStrength>().begin(),
                                                   ndk::enum_range<EffectStrength>().end()};

INSTANTIATE_TEST_CASE_P(VibratorTests, EffectsTest,
                        Combine(ValuesIn(kEffects.begin(), kEffects.end()),
                                ValuesIn(kEffectStrengths.begin(), kEffectStrengths.end())),
                        EffectsTest::PrintParam);

struct PrimitiveParam {
    CompositePrimitive primitive;
    EffectIndex index;
};

class PrimitiveTest : public VibratorTest, public WithParamInterface<PrimitiveParam> {
  public:
    static auto PrintParam(const TestParamInfo<ParamType> &info) {
        return toString(info.param.primitive);
    }
};

const std::vector<PrimitiveParam> kPrimitiveParams = {
        {CompositePrimitive::CLICK, 2},      {CompositePrimitive::THUD, 4},
        {CompositePrimitive::SPIN, 5},       {CompositePrimitive::QUICK_RISE, 6},
        {CompositePrimitive::SLOW_RISE, 7},  {CompositePrimitive::QUICK_FALL, 8},
        {CompositePrimitive::LIGHT_TICK, 9}, {CompositePrimitive::LOW_TICK, 10},
};

TEST_P(PrimitiveTest, getPrimitiveDuration) {
    auto param = GetParam();
    auto primitive = param.primitive;
    auto index = param.index;
    int32_t duration;

    EXPECT_EQ(EX_NONE, mVibrator->getPrimitiveDuration(primitive, &duration).getExceptionCode());
    EXPECT_EQ(EFFECT_DURATIONS[index], duration);
}

INSTANTIATE_TEST_CASE_P(VibratorTests, PrimitiveTest,
                        ValuesIn(kPrimitiveParams.begin(), kPrimitiveParams.end()),
                        PrimitiveTest::PrintParam);

struct ComposeParam {
    std::string name;
    std::vector<CompositeEffect> composite;
    EffectQueue queue;
};

class ComposeTest : public VibratorTest, public WithParamInterface<ComposeParam> {
  public:
    static auto PrintParam(const TestParamInfo<ParamType> &info) { return info.param.name; }
};

TEST_P(ComposeTest, compose) {
    auto param = GetParam();
    auto composite = param.composite;
    auto queue = std::get<0>(param.queue);
    ExpectationSet eSetup;
    Expectation eActivate, ePollHaptics, ePollStop, eEraseDone;
    auto callback = ndk::SharedRefBase::make<MockVibratorCallback>();
    std::promise<void> promise;
    std::future<void> future{promise.get_future()};
    auto complete = [&promise] {
        promise.set_value();
        return ndk::ScopedAStatus::ok();
    };

    eSetup += EXPECT_CALL(*mMockApi, setFFGain(_, ON_GLOBAL_SCALE))
                      .After(eSetup)
                      .WillOnce(DoDefault());
    eSetup += EXPECT_CALL(*mMockApi, getOwtFreeSpace(_)).WillOnce(DoDefault());
    eSetup += EXPECT_CALL(*mMockApi, uploadOwtEffect(_, _, _, _, _, _))
                      .After(eSetup)
                      .WillOnce(DoDefault());
    eActivate = EXPECT_CALL(*mMockApi, setFFPlay(_, WAVEFORM_COMPOSE, true))
                        .After(eSetup)
                        .WillOnce(DoDefault());

    ePollHaptics = EXPECT_CALL(*mMockApi, pollVibeState(1, POLLING_TIMEOUT))
                           .After(eActivate)
                           .WillOnce(DoDefault());
    ePollStop =
            EXPECT_CALL(*mMockApi, pollVibeState(0, -1)).After(ePollHaptics).WillOnce(DoDefault());
    eEraseDone =
            EXPECT_CALL(*mMockApi, eraseOwtEffect(_, _, _)).After(ePollStop).WillOnce(DoDefault());
    EXPECT_CALL(*callback, onComplete()).After(eEraseDone).WillOnce(complete);

    EXPECT_EQ(EX_NONE, mVibrator->compose(composite, callback).getExceptionCode());

    EXPECT_EQ(future.wait_for(std::chrono::milliseconds(100)), std::future_status::ready);
}

const std::vector<ComposeParam> kComposeParams = {
        {"click",
         {{0, CompositePrimitive::CLICK, 1.0f}},
         Queue(QueueEffect(2, Level(1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
        {"thud",
         {{1, CompositePrimitive::THUD, 0.8f}},
         Queue(1, QueueEffect(4, Level(0.8f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
        {"spin",
         {{2, CompositePrimitive::SPIN, 0.6f}},
         Queue(2, QueueEffect(5, Level(0.6f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
        {"quick_rise",
         {{3, CompositePrimitive::QUICK_RISE, 0.4f}},
         Queue(3, QueueEffect(6, Level(0.4f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])), 0)},
        {"slow_rise",
         {{4, CompositePrimitive::SLOW_RISE, 0.0f}},
         Queue(4, QueueEffect(7, Level(0.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
        {"quick_fall",
         {{5, CompositePrimitive::QUICK_FALL, 1.0f}},
         Queue(5, QueueEffect(8, Level(1.0f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])), 0)},
        {"pop",
         {{6, CompositePrimitive::SLOW_RISE, 1.0f}, {50, CompositePrimitive::THUD, 1.0f}},
         Queue(6, QueueEffect(7, Level(1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 50,
               QueueEffect(4, Level(1.0f, V_CLICK_DEFAULT[0], V_CLICK_DEFAULT[1])), 0)},
        {"snap",
         {{7, CompositePrimitive::QUICK_RISE, 1.0f}, {0, CompositePrimitive::QUICK_FALL, 1.0f}},
         Queue(7, QueueEffect(6, Level(1.0f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])),
               QueueEffect(8, Level(1.0f, V_LONG_DEFAULT[0], V_LONG_DEFAULT[1])), 0)},
};

INSTANTIATE_TEST_CASE_P(VibratorTests, ComposeTest,
                        ValuesIn(kComposeParams.begin(), kComposeParams.end()),
                        ComposeTest::PrintParam);
}  // namespace vibrator
}  // namespace hardware
}  // namespace android
}  // namespace aidl
