/*
 * Copyright (C) 2006-2019 Apple Inc. All rights reserved.
 * Copyright (C) Research In Motion Limited 2009-2010. 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. 
 */

#pragma once

#include <JavaScriptCore/Forward.h>
#include <variant>
#include <wtf/FileSystem.h>
#include <wtf/Forward.h>
#include <wtf/Function.h>
#include <wtf/Span.h>
#include <wtf/ThreadSafeRefCounted.h>
#include <wtf/Vector.h>
#include <wtf/text/WTFString.h>

#if USE(CF)
#include <wtf/RetainPtr.h>
#endif

#if USE(GLIB)
#include <wtf/glib/GRefPtr.h>
typedef struct _GBytes GBytes;
#endif

#if USE(GSTREAMER)
#include "GStreamerCommon.h"
#endif

#if USE(FOUNDATION)
OBJC_CLASS NSArray;
OBJC_CLASS NSData;
#endif

namespace WTF {
namespace Persistence {
class Decoder;
}
}

namespace WebCore {

class SharedBufferDataView;

class WEBCORE_EXPORT SharedBuffer : public ThreadSafeRefCounted<SharedBuffer> {
public:
    static Ref<SharedBuffer> create() { return adoptRef(*new SharedBuffer); }
    static Ref<SharedBuffer> create(const uint8_t* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
    static Ref<SharedBuffer> create(const char* data, size_t size) { return adoptRef(*new SharedBuffer(data, size)); }
    static Ref<SharedBuffer> create(FileSystem::MappedFileData&& mappedFileData) { return adoptRef(*new SharedBuffer(WTFMove(mappedFileData))); }

    enum class MayUseFileMapping : bool { No, Yes };
    static RefPtr<SharedBuffer> createWithContentsOfFile(const String& filePath, FileSystem::MappedFileMode = FileSystem::MappedFileMode::Shared, MayUseFileMapping = MayUseFileMapping::Yes);

    static Ref<SharedBuffer> create(Vector<uint8_t>&&);

#if USE(FOUNDATION)
    RetainPtr<NSData> createNSData() const;
    RetainPtr<NSArray> createNSDataArray() const;
    static Ref<SharedBuffer> create(NSData *);
    void append(NSData *);
#endif
#if USE(CF)
    RetainPtr<CFDataRef> createCFData() const;
    static Ref<SharedBuffer> create(CFDataRef);
    void append(CFDataRef);
#endif

#if USE(GLIB)
    static Ref<SharedBuffer> create(GBytes*);
    GRefPtr<GBytes> createGBytes() const;
#endif

#if USE(GSTREAMER)
    static Ref<SharedBuffer> create(GstMappedOwnedBuffer&);
#endif
    // Calling data() causes all the data segments to be copied into one segment if they are not already.
    // Iterate the segments using begin() and end() instead.
    // FIXME: Audit the call sites of this function and replace them with iteration if possible.
    const uint8_t* data() const;
    const char* dataAsCharPtr() const { return reinterpret_cast<const char*>(data()); }
    Vector<uint8_t> copyData() const;

    // Similar to copyData() but avoids copying and will take the data instead when it is safe (The SharedBuffer is not shared).
    Vector<uint8_t> extractData();

    // Creates an ArrayBuffer and copies this SharedBuffer's contents to that
    // ArrayBuffer without merging segmented buffers into a flat buffer.
    RefPtr<ArrayBuffer> tryCreateArrayBuffer() const;

    size_t size() const { return m_size; }

    bool isEmpty() const { return !size(); }

    void append(const SharedBuffer&);
    void append(const uint8_t*, size_t);
    void append(const char* data, size_t length) { append(reinterpret_cast<const uint8_t*>(data), length); }
    void append(Vector<uint8_t>&&);

    void clear();

    Ref<SharedBuffer> copy() const;
    void copyTo(void* destination, size_t length) const;
    void copyTo(void* destination, size_t offset, size_t length) const;

    // Data wrapped by a DataSegment should be immutable because it can be referenced by other objects.
    // To modify or combine the data, allocate a new DataSegment.
    class DataSegment : public ThreadSafeRefCounted<DataSegment> {
    public:
        WEBCORE_EXPORT const uint8_t* data() const;
        WEBCORE_EXPORT size_t size() const;

        static Ref<DataSegment> create(Vector<uint8_t>&& data)
        {
            data.shrinkToFit();
            return adoptRef(*new DataSegment(WTFMove(data)));
        }

#if USE(CF)
        static Ref<DataSegment> create(RetainPtr<CFDataRef>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
#endif
#if USE(GLIB)
        static Ref<DataSegment> create(GRefPtr<GBytes>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
#endif
#if USE(GSTREAMER)
        static Ref<DataSegment> create(RefPtr<GstMappedOwnedBuffer>&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }
#endif
        static Ref<DataSegment> create(FileSystem::MappedFileData&& data) { return adoptRef(*new DataSegment(WTFMove(data))); }

        struct Provider {
            Function<const uint8_t*()> data;
            Function<size_t()> size;
        };

        static Ref<DataSegment> create(Provider&& provider) { return adoptRef(*new DataSegment(WTFMove(provider))); }

#if USE(FOUNDATION)
        RetainPtr<NSData> createNSData() const;
#endif

        bool containsMappedFileData() const;

    private:
        DataSegment(Vector<uint8_t>&& data)
            : m_immutableData(WTFMove(data)) { }
#if USE(CF)
        DataSegment(RetainPtr<CFDataRef>&& data)
            : m_immutableData(WTFMove(data)) { }
#endif
#if USE(GLIB)
        DataSegment(GRefPtr<GBytes>&& data)
            : m_immutableData(WTFMove(data)) { }
#endif
#if USE(GSTREAMER)
        DataSegment(RefPtr<GstMappedOwnedBuffer>&& data)
            : m_immutableData(WTFMove(data)) { }
#endif
        DataSegment(FileSystem::MappedFileData&& data)
            : m_immutableData(WTFMove(data)) { }
        DataSegment(Provider&& provider)
            : m_immutableData(WTFMove(provider)) { }

        std::variant<Vector<uint8_t>,
#if USE(CF)
            RetainPtr<CFDataRef>,
#endif
#if USE(GLIB)
            GRefPtr<GBytes>,
#endif
#if USE(GSTREAMER)
            RefPtr<GstMappedOwnedBuffer>,
#endif
            FileSystem::MappedFileData,
            Provider> m_immutableData;
        friend class SharedBuffer;
    };

    static Ref<SharedBuffer> create(DataSegment::Provider&&);

    void forEachSegment(const Function<void(const Span<const uint8_t>&)>&) const;
    bool startsWith(const Span<const uint8_t>& prefix) const;

    struct DataSegmentVectorEntry {
        size_t beginPosition;
        Ref<DataSegment> segment;
    };
    using DataSegmentVector = Vector<DataSegmentVectorEntry, 1>;
    DataSegmentVector::const_iterator begin() const { return m_segments.begin(); }
    DataSegmentVector::const_iterator end() const { return m_segments.end(); }
    bool hasOneSegment() const;

    // begin and end take O(1) time, this takes O(log(N)) time.
    SharedBufferDataView getSomeData(size_t position) const;

    String toHexString() const;

    void hintMemoryNotNeededSoon() const;

    WTF::Persistence::Decoder decoder() const;

    bool operator==(const SharedBuffer&) const;
    bool operator!=(const SharedBuffer& other) const { return !operator==(other); }

private:
    explicit SharedBuffer() = default;
    explicit SharedBuffer(const uint8_t*, size_t);
    explicit SharedBuffer(const char*, size_t);
    explicit SharedBuffer(Vector<uint8_t>&&);
    explicit SharedBuffer(FileSystem::MappedFileData&&);
    explicit SharedBuffer(DataSegment::Provider&&);
#if USE(CF)
    explicit SharedBuffer(CFDataRef);
#endif
#if USE(GLIB)
    explicit SharedBuffer(GBytes*);
#endif
#if USE(GSTREAMER)
    explicit SharedBuffer(GstMappedOwnedBuffer&);
#endif

    void combineIntoOneSegment() const;

    // Combines all the segments into a Vector and returns that vector after clearing the SharedBuffer.
    Vector<uint8_t> takeData();
    
    static RefPtr<SharedBuffer> createFromReadingFile(const String& filePath);

    size_t m_size { 0 };
    mutable DataSegmentVector m_segments;

#if ASSERT_ENABLED
    mutable bool m_hasBeenCombinedIntoOneSegment { false };
    bool internallyConsistent() const;
#endif
};

inline Vector<uint8_t> SharedBuffer::extractData()
{
    if (hasOneRef())
        return takeData();
    return copyData();
}

class WEBCORE_EXPORT SharedBufferDataView {
public:
    SharedBufferDataView(Ref<SharedBuffer::DataSegment>&&, size_t positionWithinSegment, std::optional<size_t> newSize = std::nullopt);
    SharedBufferDataView(const SharedBufferDataView&, size_t newSize);
    size_t size() const;
    const uint8_t* data() const;
    const char* dataAsCharPtr() const { return reinterpret_cast<const char*>(data()); }
    Ref<SharedBuffer> createSharedBuffer() const;
#if USE(FOUNDATION)
    RetainPtr<NSData> createNSData() const;
#endif
private:
    const Ref<SharedBuffer::DataSegment> m_segment;
    const size_t m_positionWithinSegment;
    const size_t m_size;
};

RefPtr<SharedBuffer> utf8Buffer(const String&);

} // namespace WebCore
