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

#pragma once

#if HAVE(AVASSETREADER)

#include "ImageDecoder.h"
#include "SampleMap.h"
#include <wtf/Lock.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>

OBJC_CLASS AVAssetTrack;
OBJC_CLASS AVAssetReader;
OBJC_CLASS AVURLAsset;
OBJC_CLASS WebCoreSharedBufferResourceLoaderDelegate;
typedef struct opaqueCMSampleBuffer* CMSampleBufferRef;

namespace WTF {
class MediaTime;
}

namespace WebCore {

class ContentType;
class ImageDecoderAVFObjCSample;
class ImageRotationSessionVT;
class PixelBufferConformerCV;
class WebCoreDecompressionSession;

class ImageDecoderAVFObjC : public ImageDecoder {
public:
    WEBCORE_EXPORT static RefPtr<ImageDecoderAVFObjC> create(SharedBuffer&, const String& mimeType, AlphaOption, GammaAndColorProfileOption);
    virtual ~ImageDecoderAVFObjC();

    WEBCORE_EXPORT static bool supportsMediaType(MediaType);
    static bool supportsContainerType(const String&);

    size_t bytesDecodedToDetermineProperties() const override { return 0; }
    WEBCORE_EXPORT static bool canDecodeType(const String& mimeType);

    const String& mimeType() const { return m_mimeType; }

    WEBCORE_EXPORT void setEncodedDataStatusChangeCallback(Function<void(EncodedDataStatus)>&&) final;
    EncodedDataStatus encodedDataStatus() const final;
    WEBCORE_EXPORT IntSize size() const final;
    WEBCORE_EXPORT size_t frameCount() const final;
    RepetitionCount repetitionCount() const final;
    String uti() const final;
    String filenameExtension() const final;
    std::optional<IntPoint> hotSpot() const final { return std::nullopt; }
    String accessibilityDescription() const final { return String(); }

    IntSize frameSizeAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const final;
    bool frameIsCompleteAtIndex(size_t) const final;
    ImageDecoder::FrameMetadata frameMetadataAtIndex(size_t) const final;

    Seconds frameDurationAtIndex(size_t) const final;
    bool frameHasAlphaAtIndex(size_t) const final;
    bool frameAllowSubsamplingAtIndex(size_t) const final;
    unsigned frameBytesAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default) const final;

    WEBCORE_EXPORT PlatformImagePtr createFrameImageAtIndex(size_t, SubsamplingLevel = SubsamplingLevel::Default, const DecodingOptions& = DecodingOptions(DecodingMode::Synchronous)) final;

    WEBCORE_EXPORT void setExpectedContentSize(long long) final;
    WEBCORE_EXPORT void setData(SharedBuffer&, bool allDataReceived) final;
    bool isAllDataReceived() const final { return m_isAllDataReceived; }
    WEBCORE_EXPORT void clearFrameBufferCache(size_t) final;

    bool hasTrack() const { return !!m_track; }
    WEBCORE_EXPORT Vector<ImageDecoder::FrameInfo> frameInfos() const;

private:
    ImageDecoderAVFObjC(SharedBuffer&, const String& mimeType, AlphaOption, GammaAndColorProfileOption);

    AVAssetTrack *firstEnabledTrack();
    void readSamples();
    void readTrackMetadata();
    bool storeSampleBuffer(CMSampleBufferRef);
    void advanceCursor();
    void setTrack(AVAssetTrack *);

    const ImageDecoderAVFObjCSample* sampleAtIndex(size_t) const;
    bool sampleIsComplete(const ImageDecoderAVFObjCSample&) const;

    String m_mimeType;
    String m_uti;
    RetainPtr<AVURLAsset> m_asset;
    RetainPtr<AVAssetTrack> m_track;
    RetainPtr<WebCoreSharedBufferResourceLoaderDelegate> m_loader;
    std::unique_ptr<ImageRotationSessionVT> m_imageRotationSession;
    Ref<WebCoreDecompressionSession> m_decompressionSession;
    Function<void(EncodedDataStatus)> m_encodedDataStatusChangedCallback;

    SampleMap m_sampleData;
    DecodeOrderSampleMap::iterator m_cursor;
    Lock m_sampleGeneratorLock;
    bool m_isAllDataReceived { false };
    std::optional<IntSize> m_size;
};

}
#endif
