/*
 * Copyright (C) 2023 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

// The following includes are required because we have class definitions below
// for EndPoint and Patch, which precludes using a forward declaration only.
#include "IAfThread.h"  // IAfThreadBase IAfMmapThread IAfPlaybackThread IAfRecordThread
#include "IAfTrack.h"   // IAfPatchRecord IAfPatchTrack

#include <datapath/AudioHwDevice.h>
#include <media/DeviceDescriptorBase.h>
#include <utils/Log.h>      // ALOG used in this file
#include <utils/RefBase.h>  // avoid transitive dependency
#include <utils/Thread.h>

namespace android {

class IAfPatchPanel;
class PatchCommandThread;

class SoftwarePatch {
public:
    SoftwarePatch(
            const sp<const IAfPatchPanel>& patchPanel,
            audio_patch_handle_t patchHandle,
            audio_io_handle_t playbackThreadHandle,
            audio_io_handle_t recordThreadHandle)
        : mPatchPanel(patchPanel),
          mPatchHandle(patchHandle),
          mPlaybackThreadHandle(playbackThreadHandle),
          mRecordThreadHandle(recordThreadHandle) {}
    SoftwarePatch(const SoftwarePatch&) = default;

    status_t getLatencyMs_l(double* latencyMs) const REQUIRES(audio_utils::AudioFlinger_Mutex);
    audio_patch_handle_t getPatchHandle() const { return mPatchHandle; };
    audio_io_handle_t getPlaybackThreadHandle() const { return mPlaybackThreadHandle; };
    audio_io_handle_t getRecordThreadHandle() const { return mRecordThreadHandle; };

private:
    const sp<const IAfPatchPanel> mPatchPanel;
    const audio_patch_handle_t mPatchHandle;
    const audio_io_handle_t mPlaybackThreadHandle;
    const audio_io_handle_t mRecordThreadHandle;
};

class IAfPatchPanelCallback : public virtual RefBase {
public:
    virtual void closeThreadInternal_l(const sp<IAfPlaybackThread>& thread) REQUIRES(mutex()) = 0;
    virtual void closeThreadInternal_l(const sp<IAfRecordThread>& thread) REQUIRES(mutex()) = 0;
    virtual IAfPlaybackThread* primaryPlaybackThread_l() const REQUIRES(mutex()) = 0;
    virtual IAfPlaybackThread* checkPlaybackThread_l(audio_io_handle_t output) const
            REQUIRES(mutex()) = 0;
    virtual IAfRecordThread* checkRecordThread_l(audio_io_handle_t input) const
            REQUIRES(mutex()) = 0;
    virtual IAfMmapThread* checkMmapThread_l(audio_io_handle_t io) const REQUIRES(mutex()) = 0;
    virtual sp<IAfThreadBase> openInput_l(audio_module_handle_t module,
            audio_io_handle_t* input,
            audio_config_t* config,
            audio_devices_t device,
            const char* address,
            audio_source_t source,
            audio_input_flags_t flags,
            audio_devices_t outputDevice,
            const String8& outputDeviceAddress) REQUIRES(mutex()) = 0;
    virtual sp<IAfThreadBase> openOutput_l(audio_module_handle_t module,
            audio_io_handle_t* output,
            audio_config_t* halConfig,
            audio_config_base_t* mixerConfig,
            audio_devices_t deviceType,
            const String8& address,
            audio_output_flags_t flags) REQUIRES(mutex()) = 0;
    virtual audio_utils::mutex& mutex() const
            RETURN_CAPABILITY(audio_utils::AudioFlinger_Mutex) = 0;
    virtual const DefaultKeyedVector<audio_module_handle_t, AudioHwDevice*>&
            getAudioHwDevs_l() const REQUIRES(mutex()) = 0;
    virtual audio_unique_id_t nextUniqueId(audio_unique_id_use_t use) = 0;
    virtual const sp<PatchCommandThread>& getPatchCommandThread() = 0;
    virtual void updateDownStreamPatches_l(
            const struct audio_patch* patch, const std::set<audio_io_handle_t>& streams)
            REQUIRES(mutex()) = 0;
    virtual void updateOutDevicesForRecordThreads_l(const DeviceDescriptorBaseVector& devices)
            REQUIRES(mutex()) = 0;
};

class IAfPatchPanel : public virtual RefBase {
public:
    static sp<IAfPatchPanel> create(const sp<IAfPatchPanelCallback>& afPatchPanelCallback);

    // Extraction of inner Endpoint and Patch classes would require interfaces
    // (in the Endpoint case a templated interface) but that seems
    // excessive for now.  We keep them as inner classes until extraction
    // is needed.
    template <typename ThreadType, typename TrackType>
    class Endpoint final {
    public:
        Endpoint() = default;
        Endpoint(const Endpoint&) = delete;
        Endpoint& operator=(const Endpoint& other) noexcept {
            mThread = other.mThread;
            mCloseThread = other.mCloseThread;
            mHandle = other.mHandle;
            mTrack = other.mTrack;
            return *this;
        }
        Endpoint(Endpoint&& other) noexcept { swap(other); }
        Endpoint& operator=(Endpoint&& other) noexcept {
            swap(other);
            return *this;
        }
        ~Endpoint() {
            ALOGE_IF(
                    mHandle != AUDIO_PATCH_HANDLE_NONE,
                    "A non empty Patch Endpoint leaked, handle %d", mHandle);
        }

        status_t checkTrack(TrackType* trackOrNull) const {
            if (trackOrNull == nullptr) return NO_MEMORY;
            return trackOrNull->initCheck();
        }
        audio_patch_handle_t handle() const { return mHandle; }
        sp<ThreadType> thread() const { return mThread; }
        sp<TrackType> track() const { return mTrack; }
        sp<const ThreadType> const_thread() const { return mThread; }
        sp<const TrackType> const_track() const { return mTrack; }

        void closeConnections_l(const sp<IAfPatchPanel>& panel)
                REQUIRES(audio_utils::AudioFlinger_Mutex)
                NO_THREAD_SAFETY_ANALYSIS // this is broken in clang
        {
            if (mHandle != AUDIO_PATCH_HANDLE_NONE) {
                panel->releaseAudioPatch_l(mHandle);
                mHandle = AUDIO_PATCH_HANDLE_NONE;
            }
            if (mThread != nullptr) {
                if (mTrack != nullptr) {
                    mThread->deletePatchTrack(mTrack);
                }
                if (mCloseThread) {
                    panel->closeThreadInternal_l(mThread);
                }
            }
        }
        audio_patch_handle_t* handlePtr() { return &mHandle; }
        void setThread(const sp<ThreadType>& thread, bool closeThread = true) {
            mThread = thread;
            mCloseThread = closeThread;
        }
        template <typename T>
        void setTrackAndPeer(const sp<TrackType>& track, const sp<T>& peer, bool holdReference) {
            mTrack = track;
            mThread->addPatchTrack(mTrack);
            mTrack->setPeerProxy(peer, holdReference);
            mClearPeerProxy = holdReference;
        }
        void clearTrackPeer() {
            if (mClearPeerProxy && mTrack) mTrack->clearPeerProxy();
        }
        void stopTrack() {
            if (mTrack) mTrack->stop();
        }

        void swap(Endpoint& other) noexcept {
            using std::swap;
            swap(mThread, other.mThread);
            swap(mCloseThread, other.mCloseThread);
            swap(mClearPeerProxy, other.mClearPeerProxy);
            swap(mHandle, other.mHandle);
            swap(mTrack, other.mTrack);
        }

        friend void swap(Endpoint& a, Endpoint& b) noexcept { a.swap(b); }

    private:
        sp<ThreadType> mThread;
        bool mCloseThread = true;
        bool mClearPeerProxy = true;
        audio_patch_handle_t mHandle = AUDIO_PATCH_HANDLE_NONE;
        sp<TrackType> mTrack;
    };

    class Patch final {
    public:
        Patch(const struct audio_patch& patch, bool endpointPatch)
            : mAudioPatch(patch), mIsEndpointPatch(endpointPatch) {}
        Patch() = default;
        ~Patch();
        Patch(const Patch& other) noexcept {
            mAudioPatch = other.mAudioPatch;
            mHalHandle = other.mHalHandle;
            mPlayback = other.mPlayback;
            mRecord = other.mRecord;
            mThread = other.mThread;
            mIsEndpointPatch = other.mIsEndpointPatch;
        }
        Patch(Patch&& other) noexcept { swap(other); }
        Patch& operator=(Patch&& other) noexcept {
            swap(other);
            return *this;
        }

        void swap(Patch& other) noexcept {
            using std::swap;
            swap(mAudioPatch, other.mAudioPatch);
            swap(mHalHandle, other.mHalHandle);
            swap(mPlayback, other.mPlayback);
            swap(mRecord, other.mRecord);
            swap(mThread, other.mThread);
            swap(mIsEndpointPatch, other.mIsEndpointPatch);
        }

        friend void swap(Patch& a, Patch& b) noexcept { a.swap(b); }

        status_t createConnections_l(const sp<IAfPatchPanel>& panel)
                REQUIRES(audio_utils::AudioFlinger_Mutex);
        void clearConnections_l(const sp<IAfPatchPanel>& panel)
                REQUIRES(audio_utils::AudioFlinger_Mutex);
        bool isSoftware() const {
            return mRecord.handle() != AUDIO_PATCH_HANDLE_NONE ||
                   mPlayback.handle() != AUDIO_PATCH_HANDLE_NONE;
        }

        void setThread(const sp<IAfThreadBase>& thread) { mThread = thread; }
        wp<IAfThreadBase> thread() const { return mThread; }

        // returns the latency of the patch (from record to playback).
        status_t getLatencyMs(double* latencyMs) const;

        String8 dump(audio_patch_handle_t myHandle) const;

        // Note that audio_patch::id is only unique within a HAL module
        struct audio_patch mAudioPatch;
        // handle for audio HAL patch handle present only when the audio HAL version is >= 3.0
        audio_patch_handle_t mHalHandle = AUDIO_PATCH_HANDLE_NONE;
        // below members are used by a software audio patch connecting a source device from a
        // given audio HW module to a sink device on an other audio HW module.
        // the objects are created by createConnections() and released by clearConnections()
        // playback thread is created if no existing playback thread can be used
        // connects playback thread output to sink device
        Endpoint<IAfPlaybackThread, IAfPatchTrack> mPlayback;
        // connects source device to record thread input
        Endpoint<IAfRecordThread, IAfPatchRecord> mRecord;

        wp<IAfThreadBase> mThread;
        bool mIsEndpointPatch;
    };

    /* List connected audio ports and their attributes */
    virtual status_t listAudioPorts_l(unsigned int* num_ports, struct audio_port* ports)
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    /* Get supported attributes for a given audio port */
    virtual status_t getAudioPort_l(struct audio_port_v7* port)
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    /* Create a patch between several source and sink ports */
    virtual status_t createAudioPatch_l(
            const struct audio_patch* patch,
            audio_patch_handle_t* handle,
            bool endpointPatch = false)
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    /* Release a patch */
    virtual status_t releaseAudioPatch_l(audio_patch_handle_t handle)
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    /* List connected audio devices and they attributes */
    virtual status_t listAudioPatches_l(unsigned int* num_patches, struct audio_patch* patches)
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    // Retrieves all currently estrablished software patches for a stream
    // opened on an intermediate module.
    virtual status_t getDownstreamSoftwarePatches(
            audio_io_handle_t stream, std::vector<SoftwarePatch>* patches) const = 0;

    // Notifies patch panel about all opened and closed streams.
    virtual void notifyStreamOpened(
            AudioHwDevice* audioHwDevice, audio_io_handle_t stream, struct audio_patch* patch) = 0;

    virtual void notifyStreamClosed(audio_io_handle_t stream) = 0;

    virtual void dump(int fd) const = 0;

    virtual const std::map<audio_patch_handle_t, Patch>& patches_l() const
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    virtual status_t getLatencyMs_l(audio_patch_handle_t patchHandle, double* latencyMs) const
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    virtual void closeThreadInternal_l(const sp<IAfThreadBase>& thread) const
            REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;

    /**
     * Get the attributes of the mix port when connecting to the given device port.
     */
    virtual status_t getAudioMixPort_l(
            const struct audio_port_v7* devicePort,
            struct audio_port_v7* mixPort) REQUIRES(audio_utils::AudioFlinger_Mutex) = 0;
};

}  // namespace android
