/*
 * Copyright (C) 2021 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.
 */
#pragma once

#include <algorithm>
#include <cmath>

#include "HardwareBase.h"
#include "Vibrator.h"

#define PROC_SND_PCM "/proc/asound/pcm"
#define HAPTIC_PCM_DEVICE_SYMBOL "haptic nohost playback"

static struct pcm_config haptic_nohost_config = {
        .channels = 1,
        .rate = 48000,
        .period_size = 80,
        .period_count = 2,
        .format = PCM_FORMAT_S16_LE,
};

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,
};

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

class HwApi : public Vibrator::HwApi, private HwApiBase {
  public:
    static std::unique_ptr<HwApi> Create() {
        auto hwapi = std::unique_ptr<HwApi>(new HwApi());
        return hwapi;
    }
    HwApi() {
        open("calibration/f0_stored", &mF0);
        open("default/f0_offset", &mF0Offset);
        open("calibration/redc_stored", &mRedc);
        open("calibration/q_stored", &mQ);
        open("default/vibe_state", &mVibeState);
        open("default/num_waves", &mEffectCount);
        open("default/owt_free_space", &mOwtFreeSpace);
        open("default/f0_comp_enable", &mF0CompEnable);
        open("default/redc_comp_enable", &mRedcCompEnable);
        open("default/delay_before_stop_playback_us", &mMinOnOffInterval);
    }

    bool setF0(std::string value) override { return set(value, &mF0); }
    bool setF0Offset(uint32_t value) override { return set(value, &mF0Offset); }
    bool setRedc(std::string value) override { return set(value, &mRedc); }
    bool setQ(std::string value) override { return set(value, &mQ); }
    bool getEffectCount(uint32_t *value) override { return get(value, &mEffectCount); }
    bool pollVibeState(uint32_t value, int32_t timeoutMs) override {
        return poll(value, &mVibeState, timeoutMs);
    }
    bool hasOwtFreeSpace() override { return has(mOwtFreeSpace); }
    bool getOwtFreeSpace(uint32_t *value) override { return get(value, &mOwtFreeSpace); }
    bool setF0CompEnable(bool value) override { return set(value, &mF0CompEnable); }
    bool setRedcCompEnable(bool value) override { return set(value, &mRedcCompEnable); }
    bool setMinOnOffInterval(uint32_t value) override { return set(value, &mMinOnOffInterval); }
    // TODO(b/234338136): Need to add the force feedback HW API test cases
    bool setFFGain(int fd, uint16_t value) override {
        struct input_event gain = {
                .type = EV_FF,
                .code = FF_GAIN,
                .value = value,
        };
        if (write(fd, (const void *)&gain, sizeof(gain)) != sizeof(gain)) {
            return false;
        }
        return true;
    }
    bool setFFEffect(int fd, struct ff_effect *effect, uint16_t timeoutMs) override {
        if (((*effect).replay.length != timeoutMs) || (ioctl(fd, EVIOCSFF, effect) < 0)) {
            ALOGE("setFFEffect fail");
            return false;
        } else {
            return true;
        }
    }
    bool setFFPlay(int fd, int8_t index, bool value) override {
        struct input_event play = {
                .type = EV_FF,
                .code = static_cast<uint16_t>(index),
                .value = value,
        };
        if (write(fd, (const void *)&play, sizeof(play)) != sizeof(play)) {
            return false;
        } else {
            return true;
        }
    }
    bool getHapticAlsaDevice(int *card, int *device) override {
        std::string line;
        std::ifstream myfile(PROC_SND_PCM);
        if (myfile.is_open()) {
            while (getline(myfile, line)) {
                if (line.find(HAPTIC_PCM_DEVICE_SYMBOL) != std::string::npos) {
                    std::stringstream ss(line);
                    std::string currentToken;
                    std::getline(ss, currentToken, ':');
                    sscanf(currentToken.c_str(), "%d-%d", card, device);
                    return true;
                }
            }
            myfile.close();
        } else {
            ALOGE("Failed to read file: %s", PROC_SND_PCM);
        }
        return false;
    }
    bool setHapticPcmAmp(struct pcm **haptic_pcm, bool enable, int card, int device) override {
        int ret = 0;

        if (enable) {
            *haptic_pcm = pcm_open(card, device, PCM_OUT, &haptic_nohost_config);
            if (!pcm_is_ready(*haptic_pcm)) {
                ALOGE("cannot open pcm_out driver: %s", pcm_get_error(*haptic_pcm));
                goto fail;
            }

            ret = pcm_prepare(*haptic_pcm);
            if (ret < 0) {
                ALOGE("cannot prepare haptic_pcm: %s", pcm_get_error(*haptic_pcm));
                goto fail;
            }

            ret = pcm_start(*haptic_pcm);
            if (ret < 0) {
                ALOGE("cannot start haptic_pcm: %s", pcm_get_error(*haptic_pcm));
                goto fail;
            }

            return true;
        } else {
            if (*haptic_pcm) {
                pcm_close(*haptic_pcm);
                *haptic_pcm = NULL;
            }
            return true;
        }

    fail:
        pcm_close(*haptic_pcm);
        *haptic_pcm = NULL;
        return false;
    }
    bool uploadOwtEffect(int fd, uint8_t *owtData, uint32_t numBytes, struct ff_effect *effect,
                         uint32_t *outEffectIndex, int *status) override {
        (*effect).u.periodic.custom_len = numBytes / sizeof(uint16_t);
        delete[] ((*effect).u.periodic.custom_data);
        (*effect).u.periodic.custom_data = new int16_t[(*effect).u.periodic.custom_len]{0x0000};
        if ((*effect).u.periodic.custom_data == nullptr) {
            ALOGE("Failed to allocate memory for custom data\n");
            *status = EX_NULL_POINTER;
            return false;
        }
        memcpy((*effect).u.periodic.custom_data, owtData, numBytes);

        if ((*effect).id != -1) {
            ALOGE("(*effect).id != -1");
        }

        /* Create a new OWT waveform to update the PWLE or composite effect. */
        (*effect).id = -1;
        if (ioctl(fd, EVIOCSFF, effect) < 0) {
            ALOGE("Failed to upload effect %d (%d): %s", *outEffectIndex, errno, strerror(errno));
            delete[] ((*effect).u.periodic.custom_data);
            *status = EX_ILLEGAL_STATE;
            return false;
        }

        if ((*effect).id >= FF_MAX_EFFECTS || (*effect).id < 0) {
            ALOGE("Invalid waveform index after upload OWT effect: %d", (*effect).id);
            *status = EX_ILLEGAL_ARGUMENT;
            return false;
        }
        *outEffectIndex = (*effect).id;
        *status = 0;
        return true;
    }
    bool eraseOwtEffect(int fd, int8_t effectIndex, std::vector<ff_effect> *effect) override {
        uint32_t effectCountBefore, effectCountAfter, i, successFlush = 0;

        if (effectIndex < WAVEFORM_MAX_PHYSICAL_INDEX) {
            ALOGE("Invalid waveform index for OWT erase: %d", effectIndex);
            return false;
        }
        // Turn off the waiting time for SVC init phase to complete since chip
        // should already under STOP state
        setMinOnOffInterval(0);
        // Do erase flow
        if (effectIndex < WAVEFORM_MAX_INDEX) {
            /* Normal situation. Only erase the effect which we just played. */
            if (ioctl(fd, EVIOCRMFF, effectIndex) < 0) {
                ALOGE("Failed to erase effect %d (%d): %s", effectIndex, errno, strerror(errno));
            }
            for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < WAVEFORM_MAX_INDEX; i++) {
                if ((*effect)[i].id == effectIndex) {
                    (*effect)[i].id = -1;
                    break;
                }
            }
        } else {
            /* Flush all non-prestored effects of ff-core and driver. */
            getEffectCount(&effectCountBefore);
            for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < FF_MAX_EFFECTS; i++) {
                if (ioctl(fd, EVIOCRMFF, i) >= 0) {
                    successFlush++;
                }
            }
            getEffectCount(&effectCountAfter);
            ALOGW("Flushed effects: ff: %d; driver: %d -> %d; success: %d", effectIndex,
                  effectCountBefore, effectCountAfter, successFlush);
            /* Reset all OWT effect index of HAL. */
            for (i = WAVEFORM_MAX_PHYSICAL_INDEX; i < WAVEFORM_MAX_INDEX; i++) {
                (*effect)[i].id = -1;
            }
        }
        // Turn on the waiting time for SVC init phase to complete
        setMinOnOffInterval(Vibrator::MIN_ON_OFF_INTERVAL_US);
        return true;
    }

    void debug(int fd) override { HwApiBase::debug(fd); }

  private:
    std::ofstream mF0;
    std::ofstream mF0Offset;
    std::ofstream mRedc;
    std::ofstream mQ;
    std::ifstream mEffectCount;
    std::ifstream mVibeState;
    std::ifstream mOwtFreeSpace;
    std::ofstream mF0CompEnable;
    std::ofstream mRedcCompEnable;
    std::ofstream mMinOnOffInterval;
};

class HwCal : public Vibrator::HwCal, private HwCalBase {
  private:
    static constexpr char VERSION[] = "version";
    static constexpr char F0_CONFIG[] = "f0_measured";
    static constexpr char F0_CONFIG_DUAL[] = "f0_measured_dual";
    static constexpr char REDC_CONFIG[] = "redc_measured";
    static constexpr char Q_CONFIG[] = "q_measured";
    static constexpr char TICK_VOLTAGES_CONFIG[] = "v_tick";
    static constexpr char CLICK_VOLTAGES_CONFIG[] = "v_click";
    static constexpr char LONG_VOLTAGES_CONFIG[] = "v_long";

    static constexpr uint32_t VERSION_DEFAULT = 2;
    static constexpr int32_t DEFAULT_FREQUENCY_SHIFT = 0;
    static constexpr std::array<uint32_t, 2> V_TICK_DEFAULT = {1, 100};
    static constexpr std::array<uint32_t, 2> V_CLICK_DEFAULT = {1, 100};
    static constexpr std::array<uint32_t, 2> V_LONG_DEFAULT = {1, 100};

  public:
    HwCal() {}
    static std::unique_ptr<HwCal> Create() {
        auto hwcal = std::unique_ptr<HwCal>(new HwCal());
        return hwcal;
    }

    bool getVersion(uint32_t *value) override {
        if (getPersist(VERSION, value)) {
            return true;
        }
        *value = VERSION_DEFAULT;
        return true;
    }
    bool getLongFrequencyShift(int32_t *value) override {
        return getProperty("long.frequency.shift", value, DEFAULT_FREQUENCY_SHIFT);
    }
    bool getF0(std::string *value) override { return getPersist(F0_CONFIG, value); }
    bool getF0SyncOffset(uint32_t *value) override {
        std::string cal_0{8, '0'};
        std::string cal_1{8, '0'};

        if (getPersist(F0_CONFIG, &cal_0) && getPersist(F0_CONFIG_DUAL, &cal_1)) {
            float f0_0 = static_cast<float>(std::stoul(cal_0, nullptr, 16)) / (1 << 14);
            float f0_1 = static_cast<float>(std::stoul(cal_1, nullptr, 16)) / (1 << 14);
            float f0_offset = std::abs(f0_0 - f0_1)/2;

            if (f0_0 < f0_1) {
                *value = static_cast<uint32_t>(f0_offset * std::pow(2, 14));
            } else if (f0_0 > f0_1) {
                *value = static_cast<uint32_t>(std::pow(2, 24) - std::abs(f0_offset) * std::pow(2, 14));
            } else {
                *value = 0;
            }

            return true;
        } else {
            ALOGE("Vibrator: Unable to load F0_CONFIG or F0_CONFIG_DUAL config");
            *value = 0;
            return false;
        }
    }
    bool getRedc(std::string *value) override { return getPersist(REDC_CONFIG, value); }
    bool getQ(std::string *value) override { return getPersist(Q_CONFIG, value); }
    bool getTickVolLevels(std::array<uint32_t, 2> *value) override {
        if (getPersist(TICK_VOLTAGES_CONFIG, value)) {
            return true;
        }
        *value = V_TICK_DEFAULT;
        return true;
    }
    bool getClickVolLevels(std::array<uint32_t, 2> *value) override {
        if (getPersist(CLICK_VOLTAGES_CONFIG, value)) {
            return true;
        }
        *value = V_CLICK_DEFAULT;
        return true;
    }
    bool getLongVolLevels(std::array<uint32_t, 2> *value) override {
        if (getPersist(LONG_VOLTAGES_CONFIG, value)) {
            return true;
        }
        *value = V_LONG_DEFAULT;
        return true;
    }
    bool isChirpEnabled() override {
        bool value;
        getProperty("chirp.enabled", &value, false);
        return value;
    }
    bool getSupportedPrimitives(uint32_t *value) override {
        return getProperty("supported_primitives", value, (uint32_t)0);
    }
    bool isF0CompEnabled() override {
        bool value;
        getProperty("f0.comp.enabled", &value, true);
        return value;
    }
    bool isRedcCompEnabled() override {
        bool value;
        getProperty("redc.comp.enabled", &value, true);
        return value;
    }
    void debug(int fd) override { HwCalBase::debug(fd); }
};

}  // namespace vibrator
}  // namespace hardware
}  // namespace android
}  // namespace aidl
