/*
 * Copyright 2025 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#ifndef SkBmpRustCodec_DEFINED
#define SkBmpRustCodec_DEFINED

#include <memory>
#include <optional>

#include "include/codec/SkCodec.h"
#include "include/codec/SkEncodedImageFormat.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSpan.h"
#include "rust/bmp/FFI.rs.h"
#include "third_party/rust/cxx/v1/cxx.h"

struct SkEncodedInfo;
class SkData;
class SkStream;
class SkSwizzler;

// This class provides the Skia image decoding API (`SkCodec`) on top of:
// * The third-party `image` crate (containing BMP decompression and decoding
//   implemented in Rust)
// * Skia's `SkSwizzler` and `skcms_Transform` (pixel format and color space
//   transformations implemented in C++).
class SkBmpRustCodec final : public SkCodec {
public:
    // Discriminates a standalone BMP stream from a BMP embedded in an ICO file.
    // ICO streams have no "BM" file header, store a doubled height, and may carry
    // alpha via an AND mask, so they need ICO-aware metadata parsing.
    enum class StreamType { kBMP, kICO };

    static std::unique_ptr<SkBmpRustCodec> MakeFromStream(std::unique_ptr<SkStream>,
                                                          Result*,
                                                          StreamType = StreamType::kBMP);
    static std::unique_ptr<SkBmpRustCodec> MakeFromData(sk_sp<const SkData>, Result*);

    ~SkBmpRustCodec() override;

protected:
    SkBmpRustCodec(SkEncodedInfo&&,
                   std::unique_ptr<SkStream>,
                   rust::Box<rust_bmp::Reader>,
                   StreamType,
                   sk_sp<const SkData> inMemoryData);

    SkEncodedImageFormat onGetEncodedFormat() const override { return SkEncodedImageFormat::kBMP; }

    bool onRewind() override;

    bool onGetFrameInfo(int, FrameInfo*) const override;

private:
    static std::unique_ptr<SkBmpRustCodec> MakeFromStreamAndReader(
            std::unique_ptr<SkStream>,
            rust::Box<rust_bmp::ResultOfReader>,
            StreamType,
            sk_sp<const SkData>,
            Result*);

    // We cannot use the SkCodec implementation since we pass nullptr to the superclass out of
    // an abundance of caution w/r to rewinding the stream.
    //
    // TODO(crbug.com/370522089): See if `SkCodec` can be tweaked to avoid
    // the need to hide the stream from it.
    sk_sp<const SkData> getEncodedData() const override;

    // Codec implementation
    Result onGetPixels(const SkImageInfo& info,
                       void* dst,
                       size_t dstRowStride,
                       const Options& options,
                       int* rowsDecoded) override;

    // Incremental decoding support
    bool onSupportsIncrementalDecode(const SkImageInfo&) override { return true; }
    Result onStartIncrementalDecode(const SkImageInfo& dstInfo,
                                   void* dst,
                                   size_t dstRowBytes,
                                   const Options&) override;

    Result onIncrementalDecode(int* rowsDecoded) override;

    // Helper methods
    Result performFullDecode(const SkImageInfo& dstInfo, void* dst, size_t dstRowStride);
    Result initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts);
    void swizzleRow(const uint8_t* srcRow, void* dstRow);

    // Build a codec from a metadata-loaded Reader. Extracts dimensions, color
    // info, and ICC profile from `reader`, validates the pixel format, and
    // constructs the codec. Sets `*result` to the appropriate status.
    static std::unique_ptr<SkBmpRustCodec> MakeFromReader(std::unique_ptr<SkStream> stream,
                                                          rust::Box<rust_bmp::Reader> reader,
                                                          StreamType streamType,
                                                          sk_sp<const SkData> inMemoryData,
                                                          Result* result);

    // Internal state for incremental decoding
    struct DecodingState {
        SkSpan<uint8_t> fDst;
        size_t fDstRowStride;
        int fTotalRowsDecoded = 0;  // Accumulated count of rows decoded
    };

    Result incrementalDecode(DecodingState& state, int* rowsDecoded);

    std::optional<DecodingState> fIncrementalDecodingState;

    rust::Box<rust_bmp::Reader> fReader;
    std::unique_ptr<SkStream> fPrivStream;
    sk_sp<const SkData> fInMemoryData;
    std::unique_ptr<SkSwizzler> fSwizzler;

    // Whether this codec was created from a standalone BMP or a BMP embedded in
    // an ICO stream.
    const StreamType fStreamType;

    // Using 4-bytes-wide `uint32_t` for each pixel, because
    // `kXformSrcColorType = kRGBA_8888_SkColorType`.
    std::unique_ptr<uint32_t[]> fXformBuffer;
};

#endif  // SkBmpRustCodec_DEFINED
