/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#ifndef SkStream_DEFINED
#define SkStream_DEFINED

#include "include/core/SkData.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/base/SkCPUTypes.h"
#include "include/private/base/SkTo.h"

#include <cstdint>
#include <cstdio>
#include <cstring>
#include <memory>
#include <utility>
#include <vector>

class SkStreamAsset;

/**
 *  SkStream -- abstraction for a source of bytes. Subclasses can be backed by
 *  memory, or a file, or something else.
 */
class SK_API SkStream {
public:
    virtual ~SkStream() {}
    SkStream() {}

    /**
     *  Attempts to open the specified file as a stream, returns nullptr on failure.
     */
    static std::unique_ptr<SkStreamAsset> MakeFromFile(const char path[]);

    /** Reads or skips size number of bytes.
     *  If buffer == NULL, skip size bytes, return how many were skipped.
     *  If buffer != NULL, copy size bytes into buffer, return how many were copied.
     *  @param buffer when NULL skip size bytes, otherwise copy size bytes into buffer
     *  @param size the number of bytes to skip or copy
     *  @return the number of bytes actually read.
     */
    virtual size_t read(void* buffer, size_t size) = 0;

    /** Skip size number of bytes.
     *  @return the actual number bytes that could be skipped.
     */
    size_t skip(size_t size) {
        return this->read(nullptr, size);
    }

    /**
     *  Attempt to peek at size bytes.
     *  If this stream supports peeking, copy min(size, peekable bytes) into
     *  buffer, and return the number of bytes copied.
     *  If the stream does not support peeking, or cannot peek any bytes,
     *  return 0 and leave buffer unchanged.
     *  The stream is guaranteed to be in the same visible state after this
     *  call, regardless of success or failure.
     *  @param buffer Must not be NULL, and must be at least size bytes. Destination
     *      to copy bytes.
     *  @param size Number of bytes to copy.
     *  @return The number of bytes peeked/copied.
     */
    virtual size_t peek(void* /*buffer*/, size_t /*size*/) const { return 0; }

    /** Returns true when all the bytes in the stream have been read.
     *  As SkStream represents synchronous I/O, isAtEnd returns false when the
     *  final stream length isn't known yet, even when all the bytes available
     *  so far have been read.
     *  This may return true early (when there are no more bytes to be read)
     *  or late (after the first unsuccessful read).
     */
    virtual bool isAtEnd() const = 0;

    [[nodiscard]] bool readS8(int8_t*);
    [[nodiscard]] bool readS16(int16_t*);
    [[nodiscard]] bool readS32(int32_t*);
    [[nodiscard]] bool readS64(int64_t*);

    [[nodiscard]] bool readU8(uint8_t* i)   { return this->readS8((int8_t*)i); }
    [[nodiscard]] bool readU16(uint16_t* i) { return this->readS16((int16_t*)i); }
    [[nodiscard]] bool readU32(uint32_t* i) { return this->readS32((int32_t*)i); }
    [[nodiscard]] bool readU64(uint64_t* i) { return this->readS64((int64_t*)i); }

    [[nodiscard]] bool readBool(bool* b) {
        uint8_t i;
        if (!this->readU8(&i)) { return false; }
        *b = (i != 0);
        return true;
    }
    [[nodiscard]] bool readScalar(SkScalar*);
    [[nodiscard]] bool readPackedUInt(size_t*);

//SkStreamRewindable
    /** Rewinds to the beginning of the stream. Returns true if the stream is known
     *  to be at the beginning after this call returns.
     */
    virtual bool rewind() { return false; }

    /** Duplicates this stream. If this cannot be done, returns NULL.
     *  The returned stream will be positioned at the beginning of its data.
     */
    std::unique_ptr<SkStream> duplicate() const {
        return std::unique_ptr<SkStream>(this->onDuplicate());
    }
    /** Duplicates this stream. If this cannot be done, returns NULL.
     *  The returned stream will be positioned the same as this stream.
     */
    std::unique_ptr<SkStream> fork() const {
        return std::unique_ptr<SkStream>(this->onFork());
    }

//SkStreamSeekable
    /** Returns true if this stream can report its current position. */
    virtual bool hasPosition() const { return false; }
    /** Returns the current position in the stream. If this cannot be done, returns 0. */
    virtual size_t getPosition() const { return 0; }

    /** Seeks to an absolute position in the stream. If this cannot be done, returns false.
     *  If an attempt is made to seek past the end of the stream, the position will be set
     *  to the end of the stream.
     */
    virtual bool seek(size_t /*position*/) { return false; }

    /** Seeks to an relative offset in the stream. If this cannot be done, returns false.
     *  If an attempt is made to move to a position outside the stream, the position will be set
     *  to the closest point within the stream (beginning or end).
     */
    virtual bool move(long /*offset*/) { return false; }

//SkStreamAsset
    /** Returns true if this stream can report its total length. */
    virtual bool hasLength() const { return false; }
    /** Returns the total length of the stream. If this cannot be done, returns 0. */
    virtual size_t getLength() const { return 0; }

//SkStreamMemory
    /** Returns the starting address for the data. If this cannot be done, returns NULL. */
    virtual const void* getMemoryBase() { return nullptr; }
    virtual sk_sp<const SkData> getData() const { return nullptr; }

private:
    virtual SkStream* onDuplicate() const { return nullptr; }
    virtual SkStream* onFork() const { return nullptr; }

    SkStream(SkStream&&) = delete;
    SkStream(const SkStream&) = delete;
    SkStream& operator=(SkStream&&) = delete;
    SkStream& operator=(const SkStream&) = delete;
};

/** SkStreamRewindable is a SkStream for which rewind and duplicate are required. */
class SK_API SkStreamRewindable : public SkStream {
public:
    bool rewind() override = 0;
    std::unique_ptr<SkStreamRewindable> duplicate() const {
        return std::unique_ptr<SkStreamRewindable>(this->onDuplicate());
    }
private:
    SkStreamRewindable* onDuplicate() const override = 0;
};

/** SkStreamSeekable is a SkStreamRewindable for which position, seek, move, and fork are required. */
class SK_API SkStreamSeekable : public SkStreamRewindable {
public:
    std::unique_ptr<SkStreamSeekable> duplicate() const {
        return std::unique_ptr<SkStreamSeekable>(this->onDuplicate());
    }

    bool hasPosition() const override { return true; }
    size_t getPosition() const override = 0;
    bool seek(size_t position) override = 0;
    bool move(long offset) override = 0;

    std::unique_ptr<SkStreamSeekable> fork() const {
        return std::unique_ptr<SkStreamSeekable>(this->onFork());
    }
private:
    SkStreamSeekable* onDuplicate() const override = 0;
    SkStreamSeekable* onFork() const override = 0;
};

/** SkStreamAsset is a SkStreamSeekable for which getLength is required. */
class SK_API SkStreamAsset : public SkStreamSeekable {
public:
    bool hasLength() const override { return true; }
    size_t getLength() const override = 0;

    std::unique_ptr<SkStreamAsset> duplicate() const {
        return std::unique_ptr<SkStreamAsset>(this->onDuplicate());
    }
    std::unique_ptr<SkStreamAsset> fork() const {
        return std::unique_ptr<SkStreamAsset>(this->onFork());
    }
private:
    SkStreamAsset* onDuplicate() const override = 0;
    SkStreamAsset* onFork() const override = 0;
};

/** SkStreamMemory is a SkStreamAsset for which getMemoryBase is required. */
class SK_API SkStreamMemory : public SkStreamAsset {
public:
    const void* getMemoryBase() override = 0;

    std::unique_ptr<SkStreamMemory> duplicate() const {
        return std::unique_ptr<SkStreamMemory>(this->onDuplicate());
    }
    std::unique_ptr<SkStreamMemory> fork() const {
        return std::unique_ptr<SkStreamMemory>(this->onFork());
    }
private:
    SkStreamMemory* onDuplicate() const override = 0;
    SkStreamMemory* onFork() const override = 0;
};

class SK_API SkWStream {
public:
    virtual ~SkWStream();
    SkWStream() {}

    /** Called to write bytes to a SkWStream. Returns true on success
        @param buffer the address of at least size bytes to be written to the stream
        @param size The number of bytes in buffer to write to the stream
        @return true on success
    */
    virtual bool write(const void* buffer, size_t size) = 0;
    virtual void flush();

    virtual size_t bytesWritten() const = 0;

    // helpers

    bool write8(U8CPU value)   {
        uint8_t v = SkToU8(value);
        return this->write(&v, 1);
    }
    bool write16(U16CPU value) {
        uint16_t v = SkToU16(value);
        return this->write(&v, 2);
    }
    bool write32(uint32_t value) {
        return this->write(&value, 4);
    }
    bool write64(uint64_t value) {
        return this->write(&value, 8);
    }

    bool writeText(const char text[]) {
        SkASSERT(text);
        return this->write(text, std::strlen(text));
    }

    bool newline() { return this->write("\n", std::strlen("\n")); }

    bool writeDecAsText(int32_t);
    bool writeBigDecAsText(int64_t, int minDigits = 0);
    bool writeHexAsText(uint32_t, int minDigits = 0);
    bool writeScalarAsText(SkScalar);

    bool writeBool(bool v) { return this->write8(v); }
    bool writeScalar(SkScalar);
    bool writePackedUInt(size_t);

    bool writeStream(SkStream* input, size_t length);

    /**
     * This returns the number of bytes in the stream required to store
     * 'value'.
     */
    static int SizeOfPackedUInt(size_t value);

private:
    SkWStream(const SkWStream&) = delete;
    SkWStream& operator=(const SkWStream&) = delete;
};

class SK_API SkNullWStream : public SkWStream {
public:
    SkNullWStream() : fBytesWritten(0) {}

    bool write(const void* , size_t n) override { fBytesWritten += n; return true; }
    void flush() override {}
    size_t bytesWritten() const override { return fBytesWritten; }

private:
    size_t fBytesWritten;
};

////////////////////////////////////////////////////////////////////////////////////////

/** A stream that wraps a C FILE* file stream. */
class SK_API SkFILEStream : public SkStreamAsset {
public:
    /** Initialize the stream by calling sk_fopen on the specified path.
     *  This internal stream will be closed in the destructor.
     */
    explicit SkFILEStream(const char path[] = nullptr);

    /** Initialize the stream with an existing C FILE stream.
     *  The current position of the C FILE stream will be considered the
     *  beginning of the SkFILEStream and the current seek end of the FILE will be the end.
     *  The C FILE stream will be closed in the destructor.
     */
    explicit SkFILEStream(FILE* file);

    /** Initialize the stream with an existing C FILE stream.
     *  The current position of the C FILE stream will be considered the
     *  beginning of the SkFILEStream and size bytes later will be the end.
     *  The C FILE stream will be closed in the destructor.
     */
    explicit SkFILEStream(FILE* file, size_t size);

    ~SkFILEStream() override;

    static std::unique_ptr<SkFILEStream> Make(const char path[]) {
        std::unique_ptr<SkFILEStream> stream(new SkFILEStream(path));
        return stream->isValid() ? std::move(stream) : nullptr;
    }

    /** Returns true if the current path could be opened. */
    bool isValid() const { return fFILE != nullptr; }

    /** Close this SkFILEStream. */
    void close();

    size_t read(void* buffer, size_t size) override;
    bool isAtEnd() const override;

    bool rewind() override;
    std::unique_ptr<SkStreamAsset> duplicate() const {
        return std::unique_ptr<SkStreamAsset>(this->onDuplicate());
    }

    size_t getPosition() const override;
    bool seek(size_t position) override;
    bool move(long offset) override;

    std::unique_ptr<SkStreamAsset> fork() const {
        return std::unique_ptr<SkStreamAsset>(this->onFork());
    }

    size_t getLength() const override;

private:
    explicit SkFILEStream(FILE*, size_t size, size_t start);
    explicit SkFILEStream(std::shared_ptr<FILE>, size_t end, size_t start);
    explicit SkFILEStream(std::shared_ptr<FILE>, size_t end, size_t start, size_t current);

    SkStreamAsset* onDuplicate() const override;
    SkStreamAsset* onFork() const override;

    std::shared_ptr<FILE> fFILE;
    // My own council will I keep on sizes and offsets.
    // These are seek positions in the underling FILE, not offsets into the stream.
    size_t fEnd;
    size_t fStart;
    size_t fCurrent;

    using INHERITED = SkStreamAsset;
};

// A read only view into a block of memory.
class SK_API SkMemoryStream : public SkStreamMemory {
public:
    SkMemoryStream();

    /** We allocate (and free) the memory. Write to it via getMemoryBase() */
    explicit SkMemoryStream(size_t length);

    /** If copyData is true, the stream makes a private copy of the data. */
    SkMemoryStream(const void* data, size_t length, bool copyData = false);

    /** Creates the stream to read from the specified data */
    explicit SkMemoryStream(sk_sp<const SkData> data);

    /** Returns a stream with a copy of the input data. */
    static std::unique_ptr<SkMemoryStream> MakeCopy(const void* data, size_t length);

    /** Returns a stream with a bare pointer reference to the input data. */
    static std::unique_ptr<SkMemoryStream> MakeDirect(const void* data, size_t length);

    /** Returns a stream with a shared reference to the input data. */
    static std::unique_ptr<SkMemoryStream> Make(sk_sp<const SkData> data);

    /** Resets the stream to the specified data and length,
        just like the constructor.
        if copyData is true, the stream makes a private copy of the data
    */
    virtual void setMemory(const void* data, size_t length,
                           bool copyData = false);
    /** Replace any memory buffer with the specified buffer. The caller
        must have allocated data with sk_malloc or sk_realloc, since it
        will be freed with sk_free.
    */
    void setMemoryOwned(const void* data, size_t length);

    sk_sp<const SkData> getData() const override { return fData; }

    void setData(sk_sp<const SkData> data);

    const void* getAtPos();

    size_t read(void* buffer, size_t size) override;
    bool isAtEnd() const override;

    size_t peek(void* buffer, size_t size) const override;

    bool rewind() override;

    std::unique_ptr<SkMemoryStream> duplicate() const {
        return std::unique_ptr<SkMemoryStream>(this->onDuplicate());
    }

    size_t getPosition() const override;
    bool seek(size_t position) override;
    bool move(long offset) override;

    std::unique_ptr<SkMemoryStream> fork() const {
        return std::unique_ptr<SkMemoryStream>(this->onFork());
    }

    size_t getLength() const override;

    const void* getMemoryBase() override;

private:
    SkMemoryStream* onDuplicate() const override;
    SkMemoryStream* onFork() const override;

    sk_sp<const SkData> fData;
    size_t fOffset;

    using INHERITED = SkStreamMemory;
};

/////////////////////////////////////////////////////////////////////////////////////////////

class SK_API SkFILEWStream : public SkWStream {
public:
    explicit SkFILEWStream(const char path[]);
    ~SkFILEWStream() override;

    /** Returns true if the current path could be opened.
    */
    bool isValid() const { return fFILE != nullptr; }

    bool write(const void* buffer, size_t size) override;
    void flush() override;
    void fsync();
    size_t bytesWritten() const override;

private:
    FILE* fFILE;

    using INHERITED = SkWStream;
};

class SK_API SkDynamicMemoryWStream : public SkWStream {
public:
    SkDynamicMemoryWStream() = default;
    SkDynamicMemoryWStream(SkDynamicMemoryWStream&&);
    SkDynamicMemoryWStream& operator=(SkDynamicMemoryWStream&&);
    ~SkDynamicMemoryWStream() override;

    bool write(const void* buffer, size_t size) override;
    size_t bytesWritten() const override;

    bool read(void* buffer, size_t offset, size_t size);

    /** More efficient version of read(dst, 0, bytesWritten()). */
    void copyTo(void* dst) const;
    bool writeToStream(SkWStream* dst) const;

    /** Equivalent to copyTo() followed by reset(), but may save memory use. */
    void copyToAndReset(void* dst);

    /** Equivalent to writeToStream() followed by reset(), but may save memory use. */
    bool writeToAndReset(SkWStream* dst);

    /** Equivalent to writeToStream() followed by reset(), but may save memory use.
        When the dst is also a SkDynamicMemoryWStream, the implementation is constant time. */
    bool writeToAndReset(SkDynamicMemoryWStream* dst);

    /** Prepend this stream to dst, resetting this. */
    void prependToAndReset(SkDynamicMemoryWStream* dst);

    /** Return the contents as SkData, and then reset the stream. */
    sk_sp<SkData> detachAsData();

    /** Return the contents as vector, and then reset the stream. */
    std::vector<uint8_t> detachAsVector();

    /** Reset, returning a reader stream with the current content. */
    std::unique_ptr<SkStreamAsset> detachAsStream();

    /** Reset the stream to its original, empty, state. */
    void reset();
    void padToAlign4();
private:
    struct Block;
    Block*  fHead = nullptr;
    Block*  fTail = nullptr;
    size_t  fBytesWrittenBeforeTail = 0;

#ifdef SK_DEBUG
    void validate() const;
#else
    void validate() const {}
#endif

    // For access to the Block type.
    friend class SkBlockMemoryStream;
    friend class SkBlockMemoryRefCnt;

    using INHERITED = SkWStream;
};

#endif
