/*
 * Copyright (C) 2012-2020 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. ``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
 * 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 "InbandTextTrackPrivateAVF.h"

#if ENABLE(VIDEO) && (USE(AVFOUNDATION) || PLATFORM(IOS_FAMILY))

#include "ISOVTTCue.h"
#include "InbandTextTrackPrivateClient.h"
#include "Logging.h"
#include "MediaPlayer.h"
#include <JavaScriptCore/ArrayBuffer.h>
#include <JavaScriptCore/DataView.h>
#include <JavaScriptCore/Int8Array.h>
#include <pal/avfoundation/MediaTimeAVFoundation.h>
#include <wtf/MediaTime.h>
#include <wtf/StringPrintStream.h>
#include <wtf/cf/TypeCastsCF.h>
#include <wtf/text/CString.h>
#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>
#include <wtf/unicode/CharacterNames.h>

#include <pal/cf/CoreMediaSoftLink.h>

namespace WebCore {

AVFInbandTrackParent::~AVFInbandTrackParent() = default;

InbandTextTrackPrivateAVF::InbandTextTrackPrivateAVF(AVFInbandTrackParent* owner, CueFormat format)
    : InbandTextTrackPrivate(format)
    , m_owner(owner)
    , m_pendingCueStatus(None)
    , m_index(0)
    , m_hasBeenReported(false)
    , m_seeking(false)
    , m_haveReportedVTTHeader(false)
{
}

InbandTextTrackPrivateAVF::~InbandTextTrackPrivateAVF()
{
    disconnect();
}

static std::optional<SRGBA<uint8_t>> makeSimpleColorFromARGBCFArray(CFArrayRef colorArray)
{
    if (CFArrayGetCount(colorArray) < 4)
        return std::nullopt;

    float componentArray[4];
    for (int i = 0; i < 4; i++) {
        auto value = dynamic_cf_cast<CFNumberRef>(CFArrayGetValueAtIndex(colorArray, i));
        if (!value)
            return std::nullopt;

        float component;
        CFNumberGetValue(value, kCFNumberFloatType, &component);
        componentArray[i] = component;
    }

    return convertColor<SRGBA<uint8_t>>(SRGBA<float> { componentArray[1], componentArray[2], componentArray[3], componentArray[0] });
}

Ref<InbandGenericCue> InbandTextTrackPrivateAVF::processCueAttributes(CFAttributedStringRef attributedString)
{
    using namespace PAL;
    // Some of the attributes we translate into per-cue WebVTT settings are repeated on each part of an attributed string so only
    // process the first instance of each.
    enum AttributeFlags {
        Line = 1 << 0,
        Position = 1 << 1,
        Size = 1 << 2,
        Vertical = 1 << 3,
        Align = 1 << 4,
        FontName = 1 << 5
    };
    unsigned processed = 0;

    auto cueData = InbandGenericCue::create();
    StringBuilder content;
    String attributedStringValue = CFAttributedStringGetString(attributedString);
    CFIndex length = attributedStringValue.length();
    if (!length)
        return cueData;

    CFRange effectiveRange = CFRangeMake(0, 0);
    while ((effectiveRange.location + effectiveRange.length) < length) {

        CFDictionaryRef attributes = CFAttributedStringGetAttributes(attributedString, effectiveRange.location + effectiveRange.length, &effectiveRange);
        if (!attributes)
            continue;

        StringBuilder tagStart;
        String tagEnd;
        CFIndex attributeCount = CFDictionaryGetCount(attributes);
        Vector<const void*> keys(attributeCount);
        Vector<const void*> values(attributeCount);
        CFDictionaryGetKeysAndValues(attributes, keys.data(), values.data());

        for (CFIndex i = 0; i < attributeCount; ++i) {
            auto key = dynamic_cf_cast<CFStringRef>(keys[i]);
            CFTypeRef value = values[i];
            if (!key || !CFStringGetLength(key))
                continue;

            if (CFStringCompare(key, kCMTextMarkupAttribute_Alignment, 0) == kCFCompareEqualTo) {
                auto valueString = dynamic_cf_cast<CFStringRef>(value);
                if (!valueString || !CFStringGetLength(valueString))
                    continue;
                if (processed & Align)
                    continue;
                processed |= Align;

                if (CFStringCompare(valueString, kCMTextMarkupAlignmentType_Start, 0) == kCFCompareEqualTo)
                    cueData->setAlign(GenericCueData::Alignment::Start);
                else if (CFStringCompare(valueString, kCMTextMarkupAlignmentType_Middle, 0) == kCFCompareEqualTo)
                    cueData->setAlign(GenericCueData::Alignment::Middle);
                else if (CFStringCompare(valueString, kCMTextMarkupAlignmentType_End, 0) == kCFCompareEqualTo)
                    cueData->setAlign(GenericCueData::Alignment::End);
                else
                    ASSERT_NOT_REACHED();

                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_BoldStyle, 0) == kCFCompareEqualTo) {
                if (value != kCFBooleanTrue)
                    continue;

                tagStart.append("<b>");
                tagEnd = "</b>" + tagEnd;
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_ItalicStyle, 0) == kCFCompareEqualTo) {
                if (value != kCFBooleanTrue)
                    continue;

                tagStart.append("<i>");
                tagEnd = "</i>" + tagEnd;
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_UnderlineStyle, 0) == kCFCompareEqualTo) {
                if (value != kCFBooleanTrue)
                    continue;

                tagStart.append("<u>");
                tagEnd = "</u>" + tagEnd;
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_OrthogonalLinePositionPercentageRelativeToWritingDirection, 0) == kCFCompareEqualTo) {
                auto valueNumber = dynamic_cf_cast<CFNumberRef>(value);
                if (!valueNumber)
                    continue;
                if (processed & Line)
                    continue;
                processed |= Line;

                double line;
                CFNumberGetValue(valueNumber, kCFNumberFloat64Type, &line);
                cueData->setLine(line);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_TextPositionPercentageRelativeToWritingDirection, 0) == kCFCompareEqualTo) {
                auto valueNumber = dynamic_cf_cast<CFNumberRef>(value);
                if (!valueNumber)
                    continue;
                if (processed & Position)
                    continue;
                processed |= Position;

                double position;
                CFNumberGetValue(valueNumber, kCFNumberFloat64Type, &position);
                cueData->setPosition(position);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_WritingDirectionSizePercentage, 0) == kCFCompareEqualTo) {
                auto valueNumber = dynamic_cf_cast<CFNumberRef>(value);
                if (!valueNumber)
                    continue;
                if (processed & Size)
                    continue;
                processed |= Size;

                double size;
                CFNumberGetValue(valueNumber, kCFNumberFloat64Type, &size);
                cueData->setSize(size);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_VerticalLayout, 0) == kCFCompareEqualTo) {
                auto valueString = dynamic_cf_cast<CFStringRef>(value);
                if (!valueString || !CFStringGetLength(valueString))
                    continue;
                
                if (CFStringCompare(valueString, kCMTextVerticalLayout_LeftToRight, 0) == kCFCompareEqualTo)
                    tagStart.append(leftToRightMark);
                else if (CFStringCompare(valueString, kCMTextVerticalLayout_RightToLeft, 0) == kCFCompareEqualTo)
                    tagStart.append(rightToLeftMark);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_BaseFontSizePercentageRelativeToVideoHeight, 0) == kCFCompareEqualTo) {
                auto valueNumber = dynamic_cf_cast<CFNumberRef>(value);
                if (!valueNumber)
                    continue;

                double baseFontSize;
                CFNumberGetValue(valueNumber, kCFNumberFloat64Type, &baseFontSize);
                cueData->setBaseFontSize(baseFontSize);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_RelativeFontSize, 0) == kCFCompareEqualTo) {
                auto valueNumber = dynamic_cf_cast<CFNumberRef>(value);
                if (!valueNumber)
                    continue;

                double relativeFontSize;
                CFNumberGetValue(valueNumber, kCFNumberFloat64Type, &relativeFontSize);
                cueData->setRelativeFontSize(relativeFontSize);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_FontFamilyName, 0) == kCFCompareEqualTo) {
                auto valueString = dynamic_cf_cast<CFStringRef>(value);
                if (!valueString || !CFStringGetLength(valueString))
                    continue;
                if (processed & FontName)
                    continue;
                processed |= FontName;
                
                cueData->setFontName(valueString);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_ForegroundColorARGB, 0) == kCFCompareEqualTo) {
                auto arrayValue = dynamic_cf_cast<CFArrayRef>(value);
                if (!arrayValue)
                    continue;

                auto color = makeSimpleColorFromARGBCFArray(arrayValue);
                if (!color)
                    continue;
                cueData->setForegroundColor(*color);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_BackgroundColorARGB, 0) == kCFCompareEqualTo) {
                auto arrayValue = dynamic_cf_cast<CFArrayRef>(value);
                if (!arrayValue)
                    continue;

                auto color = makeSimpleColorFromARGBCFArray(arrayValue);
                if (!color)
                    continue;
                cueData->setBackgroundColor(*color);
                continue;
            }

            if (CFStringCompare(key, kCMTextMarkupAttribute_CharacterBackgroundColorARGB, 0) == kCFCompareEqualTo) {
                auto arrayValue = dynamic_cf_cast<CFArrayRef>(value);
                if (!arrayValue)
                    continue;

                auto color = makeSimpleColorFromARGBCFArray(arrayValue);
                if (!color)
                    continue;
                cueData->setHighlightColor(*color);
                continue;
            }
        }

        content.append(tagStart);
        content.append(StringView(attributedStringValue).substring(effectiveRange.location, effectiveRange.length));
        content.append(tagEnd);
    }

    if (content.length())
        cueData->setContent(content.toString());

    return cueData;
}

void InbandTextTrackPrivateAVF::processCue(CFArrayRef attributedStrings, CFArrayRef nativeSamples, const MediaTime& time)
{
    if (!client())
        return;

    processAttributedStrings(attributedStrings, time);
    processNativeSamples(nativeSamples, time);
}

void InbandTextTrackPrivateAVF::processAttributedStrings(CFArrayRef attributedStrings, const MediaTime& time)
{
    CFIndex count = attributedStrings ? CFArrayGetCount(attributedStrings) : 0;

    if (count)
        INFO_LOG(LOGIDENTIFIER, "added ", count, count > 1 ? " cues" : " cue", " at time ", time);

    Vector<Ref<InbandGenericCue>> arrivingCues;
    if (count) {
        for (CFIndex i = 0; i < count; i++) {
            CFAttributedStringRef attributedString = static_cast<CFAttributedStringRef>(CFArrayGetValueAtIndex(attributedStrings, i));

            if (!attributedString || !CFAttributedStringGetLength(attributedString))
                continue;

            auto cueData = processCueAttributes(attributedString);
            if (!cueData->content().length())
                continue;

            cueData->setStartTime(time);
            cueData->setEndTime(MediaTime::positiveInfiniteTime());

            // AVFoundation cue "position" is to the center of the text so adjust relative to the edge because we will use it to
            // set CSS "left".
            if (cueData->position() >= 0 && cueData->size() > 0)
                cueData->setPosition(cueData->position() - cueData->size() / 2);

            cueData->setStatus(GenericCueData::Status::Partial);

            arrivingCues.append(WTFMove(cueData));
        }
    }

    if (m_pendingCueStatus != None) {
        // Cues do not have an explicit duration, they are displayed until the next "cue" (which might be empty) is emitted.
        m_currentCueEndTime = time;

        if (m_currentCueEndTime >= m_currentCueStartTime) {
            for (auto& cueData : m_cues) {
                // See if one of the newly-arrived cues is an extension of this cue.
                Vector<Ref<InbandGenericCue>> nonExtensionCues;
                for (auto& arrivingCue : arrivingCues) {
                    if (!arrivingCue->doesExtendCueData(cueData))
                        nonExtensionCues.append(WTFMove(arrivingCue));
                    else
                        INFO_LOG(LOGIDENTIFIER, "found an extension cue ", cueData.get());
                }

                bool currentCueIsExtended = (arrivingCues.size() != nonExtensionCues.size());

                arrivingCues = WTFMove(nonExtensionCues);
                
                if (currentCueIsExtended)
                    continue;

                if (m_pendingCueStatus == Valid) {
                    cueData->setEndTime(m_currentCueEndTime);
                    cueData->setStatus(GenericCueData::Status::Complete);

                    INFO_LOG(LOGIDENTIFIER, "updating cue ", cueData.get());

                    client()->updateGenericCue(cueData);
                } else {
                    // We have to assume that the implicit duration is invalid for cues delivered during a seek because the AVF decode pipeline may not
                    // see every cue, so DO NOT update cue duration while seeking.
                    INFO_LOG(LOGIDENTIFIER, "ignoring cue delivered during seek ", cueData.get());
                }
            }
        } else
            ERROR_LOG(LOGIDENTIFIER, "negative length cue(s): ", MediaTimeRange { m_currentCueStartTime, m_currentCueEndTime });

        removeCompletedCues();
    }

    if (arrivingCues.isEmpty())
        return;

    m_currentCueStartTime = time;

    for (auto& cueData : arrivingCues) {
        m_cues.append(cueData.get());
        INFO_LOG(LOGIDENTIFIER, "adding cue ", cueData.get());
        client()->addGenericCue(cueData);
    }

    m_pendingCueStatus = seeking() ? DeliveredDuringSeek : Valid;
}

void InbandTextTrackPrivateAVF::beginSeeking()
{
    // Forget any partially accumulated cue data as the seek could be to a time outside of the cue's
    // range, which will mean that the next cue delivered will result in the current cue getting the
    // incorrect duration.
    resetCueValues();
    m_seeking = true;
}

void InbandTextTrackPrivateAVF::disconnect()
{
    m_owner = 0;
    m_index = 0;
}

void InbandTextTrackPrivateAVF::removeCompletedCues()
{
    if (client()) {
        long currentCue = m_cues.size() - 1;
        for (; currentCue >= 0; --currentCue) {
            auto& cue = m_cues[currentCue];
            if (cue->status() != GenericCueData::Status::Complete)
                continue;

            INFO_LOG(LOGIDENTIFIER, "removing cue ", cue.get());

            m_cues.remove(currentCue);
        }
    }

    if (m_cues.isEmpty())
        m_pendingCueStatus = None;

    m_currentCueStartTime = MediaTime::zeroTime();
    m_currentCueEndTime = MediaTime::zeroTime();
}

void InbandTextTrackPrivateAVF::resetCueValues()
{
    if (m_currentCueEndTime && m_cues.size())
        INFO_LOG(LOGIDENTIFIER, "flushing data for cues: start = ", m_currentCueStartTime);

    if (auto* client = this->client()) {
        for (auto& cue : m_cues)
            client->removeGenericCue(cue);
    }

    m_cues.shrink(0);
    m_pendingCueStatus = None;
    m_currentCueStartTime = MediaTime::zeroTime();
    m_currentCueEndTime = MediaTime::zeroTime();
}

void InbandTextTrackPrivateAVF::setMode(InbandTextTrackPrivate::Mode newMode)
{
    if (!m_owner)
        return;

    InbandTextTrackPrivate::Mode oldMode = mode();
    InbandTextTrackPrivate::setMode(newMode);

    if (oldMode == newMode)
        return;

    m_owner->trackModeChanged();
}

void InbandTextTrackPrivateAVF::processNativeSamples(CFArrayRef nativeSamples, const MediaTime& presentationTime)
{
    using namespace PAL;

    if (!nativeSamples)
        return;

    CFIndex count = CFArrayGetCount(nativeSamples);
    if (!count)
        return;

    INFO_LOG(LOGIDENTIFIER, count, " sample buffers at time ", presentationTime);

    for (CFIndex i = 0; i < count; i++) {
        RefPtr<ArrayBuffer> buffer;
        MediaTime duration;
        CMFormatDescriptionRef formatDescription;
        if (!readNativeSampleBuffer(nativeSamples, i, buffer, duration, formatDescription))
            continue;

        auto view = JSC::DataView::create(WTFMove(buffer), 0, buffer->byteLength());
        auto peekResult = ISOBox::peekBox(view, 0);
        if (!peekResult)
            continue;

        auto type = peekResult.value().first;
        auto boxLength = peekResult.value().second;
        if (boxLength > view->byteLength()) {
            ERROR_LOG(LOGIDENTIFIER, "chunk  type = '", type, "', size = ", boxLength, " larger than buffer length!");
            continue;
        }

        INFO_LOG(LOGIDENTIFIER, "chunk  type = '", type, "', size = ", boxLength);

        do {
            if (m_haveReportedVTTHeader || !formatDescription)
                break;

            CFDictionaryRef extensions = CMFormatDescriptionGetExtensions(formatDescription);
            if (!extensions)
                break;

            CFDictionaryRef sampleDescriptionExtensions = static_cast<CFDictionaryRef>(CFDictionaryGetValue(extensions, kCMFormatDescriptionExtension_SampleDescriptionExtensionAtoms));
            if (!sampleDescriptionExtensions)
                break;
            
            CFDataRef webvttHeaderData = static_cast<CFDataRef>(CFDictionaryGetValue(sampleDescriptionExtensions, CFSTR("vttC")));
            if (!webvttHeaderData)
                break;

            unsigned length = CFDataGetLength(webvttHeaderData);
            if (!length)
                break;

            // A WebVTT header is terminated by "One or more WebVTT line terminators" so append two line feeds to make sure the parser
            // reccognized this string as a full header.
            auto header = makeString(StringView { CFDataGetBytePtr(webvttHeaderData), length }, "\n\n");

            INFO_LOG(LOGIDENTIFIER, "VTT header ", header);
            client()->parseWebVTTFileHeader(WTFMove(header));
            m_haveReportedVTTHeader = true;
        } while (0);

        if (type == ISOWebVTTCue::boxTypeName()) {
            ISOWebVTTCue cueData = ISOWebVTTCue(presentationTime, duration);
            cueData.read(view);
            INFO_LOG(LOGIDENTIFIER, "VTT cue data ", cueData);
            client()->parseWebVTTCueData(WTFMove(cueData));
        }

        m_sampleInputBuffer.remove(0, (size_t)boxLength);
    }
}

bool InbandTextTrackPrivateAVF::readNativeSampleBuffer(CFArrayRef nativeSamples, CFIndex index, RefPtr<ArrayBuffer>& buffer, MediaTime& duration, CMFormatDescriptionRef& formatDescription)
{
    using namespace PAL;
#if OS(WINDOWS) && HAVE(AVCFPLAYERITEM_CALLBACK_VERSION_2)
    return false;
#else
    CMSampleBufferRef sampleBuffer = reinterpret_cast<CMSampleBufferRef>(const_cast<void*>(CFArrayGetValueAtIndex(nativeSamples, index)));
    if (!sampleBuffer)
        return false;

    CMSampleTimingInfo timingInfo;
    OSStatus status = CMSampleBufferGetSampleTimingInfo(sampleBuffer, index, &timingInfo);
    if (status) {
        ERROR_LOG(LOGIDENTIFIER, "CMSampleBufferGetSampleTimingInfo returned error ", status, "' for sample ", index);
        return false;
    }

    duration = PAL::toMediaTime(timingInfo.duration);

    CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
    size_t bufferLength = CMBlockBufferGetDataLength(blockBuffer);
    if (bufferLength < ISOBox::minimumBoxSize()) {
        ERROR_LOG(LOGIDENTIFIER, "CMSampleBuffer size length unexpectedly small ", bufferLength);
        return false;
    }

    m_sampleInputBuffer.grow(m_sampleInputBuffer.size() + bufferLength);
    CMBlockBufferCopyDataBytes(blockBuffer, 0, bufferLength, m_sampleInputBuffer.data() + m_sampleInputBuffer.size() - bufferLength);

    buffer = ArrayBuffer::create(m_sampleInputBuffer.data(), m_sampleInputBuffer.size());

    formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer);

    return true;
#endif
}

} // namespace WebCore

#endif // ENABLE(VIDEO) && (USE(AVFOUNDATION) || PLATFORM(IOS_FAMILY))
