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

#include <memory>
#include <optional>

#include "experimental/rust_jpeg/ffi/FFI.rs.h"
#include "include/codec/SkCodec.h"
#include "include/codec/SkEncodedImageFormat.h"
#include "include/codec/SkEncodedOrigin.h"
#include "include/core/SkSpan.h"
#include "third_party/rust/cxx/v1/cxx.h"

class SkStream;
class SkSwizzler;
struct SkEncodedInfo;

// This class provides the Skia image decoding API (`SkCodec`) on top of:
// * The third-party `zune-jpeg` crate (containing JPEG decompression and
//   decoding implemented in Rust)
// * Skia's `SkSwizzler` and `skcms_Transform` (pixel format and color space
//   transformations implemented in C++).
class SkJpegRustCodec final : public SkCodec {
public:
    static std::unique_ptr<SkJpegRustCodec> MakeFromStream(std::unique_ptr<SkStream>, Result*);

    ~SkJpegRustCodec() override;

protected:
    SkJpegRustCodec(SkEncodedInfo&&,
                    std::unique_ptr<SkStream>,
                    rust::Box<rust_jpeg::Reader>,
                    SkEncodedOrigin origin = kDefault_SkEncodedOrigin);

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

    bool onRewind() override;

    bool onSupportsIncrementalDecode(const SkImageInfo&) override { return true; }

    bool onGetFrameInfo(int, FrameInfo*) const override;

    bool onGetGainmapInfo(SkGainmapInfo* info,
                          std::unique_ptr<SkStream>* gainmapImageStream) override;

    bool onGetGainmapCodec(SkGainmapInfo* info, std::unique_ptr<SkCodec>* gainmapCodec) override;

    bool onQueryYUVAInfo(const SkYUVAPixmapInfo::SupportedDataTypes&,
                         SkYUVAPixmapInfo*) const override;

    Result onGetYUVAPlanes(const SkYUVAPixmaps&) override;

private:
    sk_sp<const SkData> getEncodedData() const override;

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

    // Incremental decoding exposes stable baseline scanlines as they become
    // available and replaceable full-frame previews after progressive scans.
    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,
                             int* rowsDecoded = nullptr);
    Result initializeSwizzler(const SkImageInfo& dstInfo, const Options& opts);
    void swizzleRow(const uint8_t* srcRow, void* dstRow);

    struct DecodingState {
        SkSpan<uint8_t> fDst;
        size_t fDstRowStride;
        int fTotalRowsInitialized = 0;
    };

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

    std::optional<DecodingState> fIncrementalDecodingState;

    // Stored separately; SkCodec base gets nullptr. Keep this before fReader so
    // the stream outlives the Rust reader's stream adapter.
    std::unique_ptr<SkStream> fPrivStream;
    rust::Box<rust_jpeg::Reader> fReader;
    std::unique_ptr<SkSwizzler> fSwizzler;

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

    // TODO: Add onGetScaledDimensions for 1/2, 1/4, 1/8 IDCT scaling
    //   (requires zune-jpeg support or post-decode downscale).
    // NOTE: Progressive scan limit (100) is enforced by zune-jpeg's default
    //   DecoderOptions, matching Blink's ProgressMonitor.
    // NOTE: APP11 (C2PA/JUMBF) segments are captured by the Rust segment
    //   scanner and forwarded to SkJpegMetadataDecoder automatically.
};

#endif  // SkJpegRustCodec_DEFINED
