/*
**
** Copyright 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.
*/

#pragma once

#include <aidl/android/hardware/audio/core/sounddose/ISoundDose.h>
#include <aidl/android/media/audio/common/AudioDevice.h>
#include <android/media/BnSoundDose.h>
#include <android/media/ISoundDoseCallback.h>
#include <media/AudioDeviceTypeAddr.h>
#include <audio_utils/MelAggregator.h>
#include <audio_utils/MelProcessor.h>
#include <binder/Status.h>
#include <mutex>
#include <unordered_map>

namespace android {

using aidl::android::hardware::audio::core::sounddose::ISoundDose;

class IMelReporterCallback : public virtual RefBase {
public:
    IMelReporterCallback() {};
    virtual ~IMelReporterCallback() {};

    virtual void stopMelComputationForDeviceId(audio_port_handle_t deviceId) = 0;
    virtual void startMelComputationForDeviceId(audio_port_handle_t deviceId) = 0;
};

class SoundDoseManager : public audio_utils::MelProcessor::MelCallback {
public:
    /** CSD is computed with a rolling window of 7 days. */
    static constexpr int64_t kCsdWindowSeconds = 604800;  // 60s * 60m * 24h * 7d
    /** Default RS2 upper bound in dBA as defined in IEC 62368-1 3rd edition. */
    static constexpr float kDefaultRs2UpperBound = 100.f;

    explicit SoundDoseManager(const sp<IMelReporterCallback>& melReporterCallback)
        : mMelReporterCallback(melReporterCallback),
          mMelAggregator(sp<audio_utils::MelAggregator>::make(kCsdWindowSeconds)),
          mRs2UpperBound(kDefaultRs2UpperBound) {};

    /**
     * \brief Creates or gets the MelProcessor assigned to the streamHandle
     *
     * \param deviceId          id for the devices where the stream is active.
     * \param streamHandle      handle to the stream
     * \param sampleRate        sample rate for the processor
     * \param channelCount      number of channels to be processed.
     * \param format            format of the input samples.
     *
     * \return MelProcessor assigned to the stream and device id.
     */
    sp<audio_utils::MelProcessor> getOrCreateProcessorForDevice(audio_port_handle_t deviceId,
                                                                audio_io_handle_t streamHandle,
                                                                uint32_t sampleRate,
                                                                size_t channelCount,
                                                                audio_format_t format);

    /**
     * \brief Removes stream processor when MEL computation is not needed anymore
     *
     * \param streamHandle      handle to the stream
     */
    void removeStreamProcessor(audio_io_handle_t streamHandle);

    /**
     * Sets the output RS2 upper bound for momentary exposure warnings. Must not be
     * higher than 100dBA and not lower than 80dBA.
     *
     * \param rs2Value value to use for momentary exposure
     */
    void setOutputRs2UpperBound(float rs2Value);

    /**
     * \brief Registers the interface for passing callbacks to the AudioService and gets
     * the ISoundDose interface.
     *
     * \returns the sound dose binder to send commands to the SoundDoseManager
     **/
    sp<media::ISoundDose> getSoundDoseInterface(const sp<media::ISoundDoseCallback>& callback);

    /**
     * Sets the HAL sound dose interface for a specific module to use for the MEL computation.
     *
     * @return true if setting the HAL sound dose value was successful, false otherwise.
     */
    bool setHalSoundDoseInterface(const std::string &module,
                                  const std::shared_ptr<ISoundDose> &halSoundDose);

    /** Reset all the stored HAL sound dose interface. */
    void resetHalSoundDoseInterfaces();

    /** Returns the cached audio port id from the active devices. */
    audio_port_handle_t getIdForAudioDevice(
            const aidl::android::media::audio::common::AudioDevice& audioDevice) const;

    /** Caches mapping between address, device port id and device type. */
    void mapAddressToDeviceId(const AudioDeviceTypeAddr& adt, const audio_port_handle_t deviceId);

    /** Clear all map entries with passed audio_port_handle_t. */
    void clearMapDeviceIdEntries(audio_port_handle_t deviceId);

    /** Returns true if CSD is enabled. */
    bool isCsdEnabled();

    void initCachedAudioDeviceCategories(
            const std::vector<media::ISoundDose::AudioDeviceCategory>& deviceCategories);

    void setAudioDeviceCategory(
            const media::ISoundDose::AudioDeviceCategory& audioDevice);

    /**
     * Returns true if the type can compute CSD. For bluetooth devices we rely on whether we
     * categorized the address as headphones/headsets, only in this case we return true.
     */
    bool shouldComputeCsdForDeviceWithAddress(const audio_devices_t type,
                                              const std::string& deviceAddress);
    /** Returns true for all device types which could support CSD computation. */
    bool shouldComputeCsdForDeviceType(audio_devices_t device);

    std::string dump() const;

    // used for testing only
    size_t getCachedMelRecordsSize() const;
    bool isFrameworkMelForced() const;
    bool isComputeCsdForcedOnAllDevices() const;

    /** Method for converting from audio_utils::CsdRecord to media::SoundDoseRecord. */
    static media::SoundDoseRecord csdRecordToSoundDoseRecord(const audio_utils::CsdRecord& legacy);

    // ------ Override audio_utils::MelProcessor::MelCallback ------
    void onNewMelValues(const std::vector<float>& mels, size_t offset, size_t length,
                        audio_port_handle_t deviceId) const override;

    void onMomentaryExposure(float currentMel, audio_port_handle_t deviceId) const override;

private:
    class SoundDose : public media::BnSoundDose,
                      public IBinder::DeathRecipient {
    public:
        SoundDose(SoundDoseManager* manager, const sp<media::ISoundDoseCallback>& callback)
            : mSoundDoseManager(manager),
              mSoundDoseCallback(callback) {}

        /** IBinder::DeathRecipient. Listen to the death of ISoundDoseCallback. */
        void binderDied(const wp<IBinder>& who) override;

        /** BnSoundDose override */
        binder::Status setOutputRs2UpperBound(float value) override;
        binder::Status resetCsd(float currentCsd,
                                const std::vector<media::SoundDoseRecord>& records) override;
        binder::Status updateAttenuation(float attenuationDB, int device) override;
        binder::Status getOutputRs2UpperBound(float* value) override;
        binder::Status setCsdEnabled(bool enabled) override;

        binder::Status initCachedAudioDeviceCategories(
                const std::vector<media::ISoundDose::AudioDeviceCategory> &btDeviceCategories)
                override;

        binder::Status setAudioDeviceCategory(
                const media::ISoundDose::AudioDeviceCategory& btAudioDevice) override;

        binder::Status getCsd(float* value) override;
        binder::Status forceUseFrameworkMel(bool useFrameworkMel) override;
        binder::Status forceComputeCsdOnAllDevices(bool computeCsdOnAllDevices) override;
        binder::Status isSoundDoseHalSupported(bool* value) override;

        wp<SoundDoseManager> mSoundDoseManager;
        const sp<media::ISoundDoseCallback> mSoundDoseCallback;
    };

    class HalSoundDoseCallback : public ISoundDose::BnHalSoundDoseCallback {
    public:
        explicit HalSoundDoseCallback(SoundDoseManager* manager)
            : mSoundDoseManager(manager) {}

        ndk::ScopedAStatus onMomentaryExposureWarning(
                float in_currentDbA,
                const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;
        ndk::ScopedAStatus onNewMelValues(
                const ISoundDose::IHalSoundDoseCallback::MelRecord& in_melRecord,
                const aidl::android::media::audio::common::AudioDevice& in_audioDevice) override;

        wp<SoundDoseManager> mSoundDoseManager;
        std::mutex mCbLock;
    };

    void resetSoundDose();

    void resetCsd(float currentCsd, const std::vector<media::SoundDoseRecord>& records);

    sp<media::ISoundDoseCallback> getSoundDoseCallback() const;

    void updateAttenuation(float attenuationDB, audio_devices_t deviceType);
    void setCsdEnabled(bool enabled);
    void setUseFrameworkMel(bool useFrameworkMel);
    void setComputeCsdOnAllDevices(bool computeCsdOnAllDevices);
    bool isSoundDoseHalSupported() const;
    /**
     * Returns true if there is one active HAL sound dose interface or null if internal MEL
     * computation is used.
     **/
    bool useHalSoundDose() const;

    mutable std::mutex mLock;

    const sp<IMelReporterCallback> mMelReporterCallback;

    // no need for lock since MelAggregator is thread-safe
    const sp<audio_utils::MelAggregator> mMelAggregator;

    std::unordered_map<audio_io_handle_t, wp<audio_utils::MelProcessor>> mActiveProcessors
            GUARDED_BY(mLock);

    // map active device address and type to device id, used also for managing the pause/resume
    // logic for deviceId's that should not report MEL values (e.g.: do not have an active MUSIC
    // or GAME stream).
    std::map<AudioDeviceTypeAddr, audio_port_handle_t> mActiveDevices GUARDED_BY(mLock);
    std::unordered_map<audio_port_handle_t, audio_devices_t> mActiveDeviceTypes GUARDED_BY(mLock);

    struct bt_device_type_hash {
        std::size_t operator() (const std::pair<std::string, audio_devices_t> &deviceType) const {
            return std::hash<std::string>()(deviceType.first) ^
                   std::hash<audio_devices_t>()(deviceType.second);
        }
    };
    // storing the BT cached information as received from the java side
    // see SoundDoseManager::setCachedAudioDeviceCategories
    std::unordered_map<std::pair<std::string, audio_devices_t>, bool, bt_device_type_hash>
            mBluetoothDevicesWithCsd GUARDED_BY(mLock);

    float mRs2UpperBound GUARDED_BY(mLock);
    std::unordered_map<audio_devices_t, float> mMelAttenuationDB GUARDED_BY(mLock);

    sp<SoundDose> mSoundDose GUARDED_BY(mLock);

    std::unordered_map<std::string, std::shared_ptr<ISoundDose>> mHalSoundDose GUARDED_BY(mLock);
    std::shared_ptr<HalSoundDoseCallback> mHalSoundDoseCallback GUARDED_BY(mLock);

    bool mUseFrameworkMel GUARDED_BY(mLock) = false;
    bool mComputeCsdOnAllDevices GUARDED_BY(mLock) = false;

    bool mEnabledCsd GUARDED_BY(mLock) = true;
};

}  // namespace android
