/*
 * Copyright (C) 2017 Apple Inc. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "config.h"
#include "AudioTrackPrivateMediaStreamCocoa.h"

#include "AudioSampleBufferList.h"
#include "AudioSampleDataSource.h"
#include "AudioSession.h"
#include "CAAudioStreamDescription.h"
#include "Logging.h"

#include <pal/cf/CoreMediaSoftLink.h>
#include <pal/spi/cocoa/AudioToolboxSPI.h>

#if ENABLE(VIDEO_TRACK) && ENABLE(MEDIA_STREAM)

namespace WebCore {

AudioTrackPrivateMediaStreamCocoa::AudioTrackPrivateMediaStreamCocoa(MediaStreamTrackPrivate& track)
    : AudioTrackPrivateMediaStream(track)
{
    track.source().addObserver(*this);
}

AudioTrackPrivateMediaStreamCocoa::~AudioTrackPrivateMediaStreamCocoa()
{
    clear();
}

void AudioTrackPrivateMediaStreamCocoa::clear()
{
    if (m_isCleared)
        return;

    m_isCleared = true;
    streamTrack().source().removeObserver(*this);

    if (m_dataSource)
        m_dataSource->setPaused(true);

    if (m_remoteIOUnit) {
        AudioOutputUnitStop(m_remoteIOUnit);
        AudioComponentInstanceDispose(m_remoteIOUnit);
        m_remoteIOUnit = nullptr;
    }

    m_dataSource = nullptr;
    m_inputDescription = nullptr;
    m_outputDescription = nullptr;
}

void AudioTrackPrivateMediaStreamCocoa::playInternal()
{
    ASSERT(isMainThread());

    if (m_isPlaying)
        return;

    m_isPlaying = true;
    m_autoPlay = false;

    if (m_dataSource)
        m_dataSource->setPaused(false);
}

void AudioTrackPrivateMediaStreamCocoa::play()
{
    playInternal();
}

void AudioTrackPrivateMediaStreamCocoa::pause()
{
    ASSERT(isMainThread());

    if (!m_isPlaying)
        return;

    m_isPlaying = false;
    m_autoPlay = false;

    if (m_dataSource)
        m_dataSource->setPaused(true);
}

void AudioTrackPrivateMediaStreamCocoa::setVolume(float volume)
{
    m_volume = volume;
    if (m_dataSource)
        m_dataSource->setVolume(m_volume);
}

AudioComponentInstance AudioTrackPrivateMediaStreamCocoa::createAudioUnit(CAAudioStreamDescription& outputDescription)
{
    AudioComponentInstance remoteIOUnit { nullptr };

    AudioComponentDescription ioUnitDescription { kAudioUnitType_Output, 0, kAudioUnitManufacturer_Apple, 0, 0 };
#if PLATFORM(IOS_FAMILY)
    ioUnitDescription.componentSubType = kAudioUnitSubType_RemoteIO;
#else
    ioUnitDescription.componentSubType = kAudioUnitSubType_DefaultOutput;
#endif

    AudioComponent ioComponent = AudioComponentFindNext(nullptr, &ioUnitDescription);
    ASSERT(ioComponent);
    if (!ioComponent) {
        ERROR_LOG(LOGIDENTIFIER, "unable to find remote IO unit component");
        return nullptr;
    }

    OSStatus err = AudioComponentInstanceNew(ioComponent, &remoteIOUnit);
    if (err) {
        ERROR_LOG(LOGIDENTIFIER, "unable to open vpio unit, error = ", err, " (", (const char*)&err, ")");
        return nullptr;
    }

#if PLATFORM(IOS_FAMILY)
    UInt32 param = 1;
    err = AudioUnitSetProperty(remoteIOUnit, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &param, sizeof(param));
    if (err) {
        ERROR_LOG(LOGIDENTIFIER, "unable to enable vpio unit output, error = ", err, " (", (const char*)&err, ")");
        return nullptr;
    }
#endif

    AURenderCallbackStruct callback = { inputProc, this };
    err = AudioUnitSetProperty(remoteIOUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, 0, &callback, sizeof(callback));
    if (err) {
        ERROR_LOG(LOGIDENTIFIER, "unable to set vpio unit speaker proc, error = ", err, " (", (const char*)&err, ")");
        return nullptr;
    }

    UInt32 size = sizeof(outputDescription.streamDescription());
    err  = AudioUnitGetProperty(remoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outputDescription.streamDescription(), &size);
    if (err) {
        ERROR_LOG(LOGIDENTIFIER, "unable to get input stream format, error = ", err, " (", (const char*)&err, ")");
        return nullptr;
    }

    outputDescription.streamDescription().mSampleRate = AudioSession::sharedSession().sampleRate();

    err = AudioUnitSetProperty(remoteIOUnit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &outputDescription.streamDescription(), sizeof(outputDescription.streamDescription()));
    if (err) {
        ERROR_LOG(LOGIDENTIFIER, "unable to set input stream format, error = ", err, " (", (const char*)&err, ")");
        return nullptr;
    }

    err = AudioUnitInitialize(remoteIOUnit);
    if (err) {
        ERROR_LOG(LOGIDENTIFIER, "AudioUnitInitialize() failed, error = ", err, " (", (const char*)&err, ")");
        return nullptr;
    }

    return remoteIOUnit;
}

// May get called on a background thread.
void AudioTrackPrivateMediaStreamCocoa::audioSamplesAvailable(const MediaTime& sampleTime, const PlatformAudioData& audioData, const AudioStreamDescription& description, size_t sampleCount)
{
    ASSERT(description.platformDescription().type == PlatformDescription::CAAudioStreamBasicType);

    if (!m_isPlaying) {
        if (m_isAudioUnitStarted) {
            if (m_remoteIOUnit)
                AudioOutputUnitStop(m_remoteIOUnit);
            m_isAudioUnitStarted = false;
        }
        return;
    }

    if (!m_inputDescription || *m_inputDescription != description) {
        m_isAudioUnitStarted = false;

        if (m_remoteIOUnit) {
            AudioOutputUnitStop(m_remoteIOUnit);
            AudioComponentInstanceDispose(m_remoteIOUnit);
            m_remoteIOUnit = nullptr;
        }

        m_inputDescription = nullptr;
        m_outputDescription = nullptr;

        CAAudioStreamDescription inputDescription = toCAAudioStreamDescription(description);
        CAAudioStreamDescription outputDescription;

        auto remoteIOUnit = createAudioUnit(outputDescription);
        if (!remoteIOUnit)
            return;

        m_inputDescription = makeUnique<CAAudioStreamDescription>(inputDescription);
        m_outputDescription = makeUnique<CAAudioStreamDescription>(outputDescription);

        m_dataSource = AudioSampleDataSource::create(description.sampleRate() * 2, streamTrack());

        if (m_dataSource->setInputFormat(inputDescription) || m_dataSource->setOutputFormat(outputDescription)) {
            AudioComponentInstanceDispose(remoteIOUnit);
            return;
        }

        if (auto error = AudioOutputUnitStart(remoteIOUnit)) {
            ERROR_LOG(LOGIDENTIFIER, "AudioOutputUnitStart failed, error = ", error, " (", (const char*)&error, ")");
            AudioComponentInstanceDispose(remoteIOUnit);
            m_inputDescription = nullptr;
            return;
        }

        m_isAudioUnitStarted = true;

        m_dataSource->setVolume(m_volume);
        m_remoteIOUnit = remoteIOUnit;
    }

    m_dataSource->pushSamples(sampleTime, audioData, sampleCount);

    if (m_autoPlay && !m_hasStartedAutoplay) {
        m_hasStartedAutoplay = true;
        callOnMainThread([this, protectedThis = makeRef(*this)] {
            if (m_autoPlay)
                playInternal();
        });
    }

    if (!m_isAudioUnitStarted) {
        if (auto error = AudioOutputUnitStart(m_remoteIOUnit)) {
            ERROR_LOG(LOGIDENTIFIER, "AudioOutputUnitStart failed, error = ", error, " (", (const char*)&error, ")");
            return;
        }
        m_isAudioUnitStarted = true;
    }
}

void AudioTrackPrivateMediaStreamCocoa::sourceStopped()
{
    pause();
}

OSStatus AudioTrackPrivateMediaStreamCocoa::render(UInt32 sampleCount, AudioBufferList& ioData, UInt32 /*inBusNumber*/, const AudioTimeStamp& timeStamp, AudioUnitRenderActionFlags& actionFlags)
{
    // This function is called on a high-priority background thread. The following protectedThis object ensures the object is not
    // destroyed on the main thread before this function exits.
    Ref<AudioTrackPrivateMediaStreamCocoa> protectedThis { *this };

    if (!m_isPlaying || m_muted || !m_dataSource || streamTrack().muted() || streamTrack().ended() || !streamTrack().enabled()) {
        AudioSampleBufferList::zeroABL(ioData, static_cast<size_t>(sampleCount * m_outputDescription->bytesPerFrame()));
        actionFlags = kAudioUnitRenderAction_OutputIsSilence;
        return 0;
    }

    m_dataSource->pullSamples(ioData, static_cast<size_t>(sampleCount), timeStamp.mSampleTime, timeStamp.mHostTime, AudioSampleDataSource::Copy);

    return 0;
}

OSStatus AudioTrackPrivateMediaStreamCocoa::inputProc(void* userData, AudioUnitRenderActionFlags* actionFlags, const AudioTimeStamp* timeStamp, UInt32 inBusNumber, UInt32 sampleCount, AudioBufferList* ioData)
{
    return static_cast<AudioTrackPrivateMediaStreamCocoa*>(userData)->render(sampleCount, *ioData, inBusNumber, *timeStamp, *actionFlags);
}


} // namespace WebCore

#endif // ENABLE(VIDEO_TRACK) && ENABLE(MEDIA_STREAM)
