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

#include "gm/gm.h"
#include "include/codec/SkCodec.h"
#include "include/codec/SkEncodedImageFormat.h"
#include "include/codec/SkPngDecoder.h"
#include "include/core/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkImage.h"
#include "include/core/SkRect.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/private/base/SkTArray.h"
#include "include/private/base/SkTemplates.h"
#include "src/base/SkAutoMalloc.h"
#include "src/core/SkSwizzlePriv.h"
#include "src/utils/SkOSPath.h"
#include "tools/flags/CommandLineFlags.h"
#include "tools/flags/CommonFlags.h"

#include <map>
#include <memory>
#include <string>
#include <vector>

DEFINE_string(pngCodecGMImages,
              "",
              "Zero or more images or directories where to find PNG images to test with "
              "PNGCodecGM. Directories are scanned non-recursively. All files are assumed to be "
              "PNG images.");
DEFINE_string(pngCodecDecodeMode,
              "",
              "One of \"get-all-pixels\", \"incremental\" or \"zero-init\".");
DEFINE_string(pngCodecDstColorType,
              "",
              "One of \"force-grayscale\", "
              "\"force-nonnative-premul-color\" or \"get-from-canvas\".");
DEFINE_string(pngCodecDstAlphaType, "", "One of \"premul\" or \"unpremul\".");

static constexpr const char* sk_color_type_to_str(SkColorType colorType) {
    switch (colorType) {
        case kUnknown_SkColorType:
            return "kUnknown_SkColorType";
        case kAlpha_8_SkColorType:
            return "kAlpha_8_SkColorType";
        case kRGB_565_SkColorType:
            return "kRGB_565_SkColorType";
        case kARGB_4444_SkColorType:
            return "kARGB_4444_SkColorType";
        case kRGBA_8888_SkColorType:
            return "kRGBA_8888_SkColorType";
        case kRGB_888x_SkColorType:
            return "kRGB_888x_SkColorType";
        case kBGRA_8888_SkColorType:
            return "kBGRA_8888_SkColorType";
        case kRGBA_1010102_SkColorType:
            return "kRGBA_1010102_SkColorType";
        case kBGRA_1010102_SkColorType:
            return "kBGRA_1010102_SkColorType";
        case kRGB_101010x_SkColorType:
            return "kRGB_101010x_SkColorType";
        case kBGR_101010x_SkColorType:
            return "kBGR_101010x_SkColorType";
        case kBGR_101010x_XR_SkColorType:
            return "kBGR_101010x_XR_SkColorType";
        case kGray_8_SkColorType:
            return "kGray_8_SkColorType";
        case kRGBA_F16Norm_SkColorType:
            return "kRGBA_F16Norm_SkColorType";
        case kRGBA_F16_SkColorType:
            return "kRGBA_F16_SkColorType";
        case kRGB_F16F16F16x_SkColorType:
            return "kRGB_F16F16F16x_SkColorType";
        case kRGBA_F32_SkColorType:
            return "kRGBA_F32_SkColorType";
        case kR8G8_unorm_SkColorType:
            return "kR8G8_unorm_SkColorType";
        case kA16_float_SkColorType:
            return "kA16_float_SkColorType";
        case kR16G16_float_SkColorType:
            return "kR16G16_float_SkColorType";
        case kA16_unorm_SkColorType:
            return "kA16_unorm_SkColorType";
        case kR16G16_unorm_SkColorType:
            return "kR16G16_unorm_SkColorType";
        case kR16G16B16A16_unorm_SkColorType:
            return "kR16G16B16A16_unorm_SkColorType";
        case kSRGBA_8888_SkColorType:
            return "kSRGBA_8888_SkColorType";
        case kR8_unorm_SkColorType:
            return "kR8_unorm_SkColorType";
        case kRGBA_10x6_SkColorType:
            return "kRGBA_10x6_SkColorType";
        case kBGRA_10101010_XR_SkColorType:
            return "kBGRA_10101010_XR_SkColorType";
    }
    SkUNREACHABLE;
}

static constexpr const char* sk_alpha_type_to_str(SkAlphaType alphaType) {
    switch (alphaType) {
        case kUnknown_SkAlphaType:
            return "kUnknown_SkAlphaType";
        case kOpaque_SkAlphaType:
            return "kOpaque_SkAlphaType";
        case kPremul_SkAlphaType:
            return "kPremul_SkAlphaType";
        case kUnpremul_SkAlphaType:
            return "kUnpremul_SkAlphaType";
    }
    SkUNREACHABLE;
}

struct DecodeResult {
    std::unique_ptr<SkCodec> codec;
    std::string errorMsg;
};

static DecodeResult decode(std::string path) {
    sk_sp<SkData> encoded(SkData::MakeFromFileName(path.c_str()));
    if (!encoded) {
        return {.errorMsg = SkStringPrintf("Could not read \"%s\".", path.c_str()).c_str()};
    }
    SkCodec::Result result;
    std::unique_ptr<SkCodec> codec = SkPngDecoder::Decode(SkMemoryStream::Make(encoded), &result);
    if (result != SkCodec::Result::kSuccess) {
        return {.errorMsg = SkStringPrintf("Could not create codec for \"%s\": %s.",
                                           path.c_str(),
                                           SkCodec::ResultToString(result))
                                    .c_str()};
    }
    return {.codec = std::move(codec)};
}

// This GM implements the PNG-related behaviors found in DM's CodecSrc class. It takes a single
// image as an argument and applies the same logic as CodecSrc.
//
// See the CodecSrc class here:
// https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.h#158.
class PNGCodecGM : public skiagm::GM {
public:
    // Based on CodecSrc::Mode.
    // https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.h#160
    enum class DecodeMode {
        kGetAllPixels,
        kIncremental,
        kZeroInit,
    };

    // Based on CodecSrc::DstColorType.
    // https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.h#172
    enum class DstColorType {
        kForceGrayscale,
        kForceNonNativePremulColor,
        kGetFromCanvas,
    };

    static constexpr const char* DecodeModeToString(DecodeMode decodeMode) {
        switch (decodeMode) {
            case DecodeMode::kGetAllPixels:
                return "kGetAllPixels";
            case DecodeMode::kIncremental:
                return "kIncremental";
            case DecodeMode::kZeroInit:
                return "kZeroInit";
        }
        SkUNREACHABLE;
    }

    static constexpr const char* DstColorTypeToString(DstColorType dstColorType) {
        switch (dstColorType) {
            case DstColorType::kForceGrayscale:
                return "kForceGrayscale";
            case DstColorType::kForceNonNativePremulColor:
                return "kForceNonNativePremulColor";
            case DstColorType::kGetFromCanvas:
                return "kGetFromCanvas";
        }
        SkUNREACHABLE;
    }

    // Based on DM's CodecSrc::CodecSrc().
    // https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.cpp#371
    PNGCodecGM(std::string path,
               DecodeMode decodeMode,
               DstColorType dstColorType,
               SkAlphaType dstAlphaType)
            : skiagm::GM()
            , fPath(path)
            , fDecodeMode(decodeMode)
            , fDstColorType(dstColorType)
            , fDstAlphaType(dstAlphaType) {}

    bool isBazelOnly() const override {
        // This GM class overlaps with DM's CodecSrc and related sources.
        return true;
    }

    std::map<std::string, std::string> getGoldKeys() const override {
        return std::map<std::string, std::string>{
                {"name", getName().c_str()},
                {"source_type", "image"},
                {"decode_mode", DecodeModeToString(fDecodeMode)},
                {"dst_color_type", DstColorTypeToString(fDstColorType)},
                {"dst_alpha_type", sk_alpha_type_to_str(fDstAlphaType)},
        };
    }

protected:
    // Based on CodecSrc::name().
    // https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.cpp#828
    SkString getName() const override {
        SkString name = SkOSPath::Basename(fPath.c_str());
        return name;
    }

    // Based on CodecSrc::size().
    // https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.cpp#803
    SkISize getISize() override {
        DecodeResult decodeResult = decode(fPath);
        if (decodeResult.errorMsg != "") {
            return {0, 0};
        }
        return decodeResult.codec->dimensions();
    }

    // Based on CodecSrc::draw().
    // https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.cpp#450
    DrawResult onDraw(SkCanvas* canvas, SkString* errorMsg) override {
        DecodeResult decodeResult = decode(fPath);
        if (decodeResult.errorMsg != "") {
            *errorMsg = decodeResult.errorMsg.c_str();
            return DrawResult::kFail;
        }
        std::unique_ptr<SkCodec> codec = std::move(decodeResult.codec);

        SkImageInfo decodeInfo = codec->getInfo();
        if (*errorMsg = validateCanvasColorTypeAndGetDecodeInfo(&decodeInfo,
                                                                canvas->imageInfo().colorType());
            *errorMsg != SkString()) {
            return DrawResult::kFail;
        }

        SkISize size = codec->dimensions();
        decodeInfo = decodeInfo.makeDimensions(size);

        const int bpp = decodeInfo.bytesPerPixel();
        const size_t rowBytes = size.width() * bpp;
        const size_t safeSize = decodeInfo.computeByteSize(rowBytes);
        SkAutoMalloc pixels(safeSize);

        SkCodec::Options options;
        if (DecodeMode::kZeroInit == fDecodeMode) {
            memset(pixels.get(), 0, size.height() * rowBytes);
            options.fZeroInitialized = SkCodec::kYes_ZeroInitialized;
        }

        // For codec srcs, we want the "draw" step to be a memcpy.  Any interesting color space or
        // color format conversions should be performed by the codec.  Sometimes the output of the
        // decode will be in an interesting color space.  On our srgb and f16 backends, we need to
        // "pretend" that the color space is standard sRGB to avoid triggering color conversion
        // at draw time.
        SkImageInfo bitmapInfo = decodeInfo.makeColorSpace(SkColorSpace::MakeSRGB());

        if (kRGBA_8888_SkColorType == decodeInfo.colorType() ||
            kBGRA_8888_SkColorType == decodeInfo.colorType()) {
            bitmapInfo = bitmapInfo.makeColorType(kN32_SkColorType);
        }

        switch (fDecodeMode) {
            case DecodeMode::kZeroInit:
            case DecodeMode::kGetAllPixels: {
                switch (codec->getPixels(decodeInfo, pixels.get(), rowBytes, &options)) {
                    case SkCodec::kSuccess:
                        // We consider these to be valid, since we should still decode what is
                        // available.
                    case SkCodec::kErrorInInput:
                    case SkCodec::kIncompleteInput:
                        break;
                    default:
                        // Everything else is considered a failure.
                        *errorMsg = SkStringPrintf("Couldn't getPixels %s.", fPath.c_str());
                        return DrawResult::kFail;
                }

                drawToCanvas(canvas, bitmapInfo, pixels.get(), rowBytes);
                break;
            }
            case DecodeMode::kIncremental: {
                void* dst = pixels.get();
                uint32_t height = decodeInfo.height();
                if (SkCodec::kSuccess ==
                    codec->startIncrementalDecode(decodeInfo, dst, rowBytes, &options)) {
                    int rowsDecoded;
                    auto result = codec->incrementalDecode(&rowsDecoded);
                    if (SkCodec::kIncompleteInput == result || SkCodec::kErrorInInput == result) {
                        codec->fillIncompleteImage(decodeInfo,
                                                   dst,
                                                   rowBytes,
                                                   SkCodec::kNo_ZeroInitialized,
                                                   height,
                                                   rowsDecoded);
                    }
                } else {
                    *errorMsg = "Could not start incremental decode";
                    return DrawResult::kFail;
                }
                drawToCanvas(canvas, bitmapInfo, dst, rowBytes);
                break;
            }
            default:
                SkASSERT(false);
                *errorMsg = "Invalid fDecodeMode";
                return DrawResult::kFail;
        }
        return DrawResult::kOk;
    }

private:
    // Checks that the canvas color type, destination color and alpha types and input image
    // constitute an interesting test case, and constructs the SkImageInfo to use when decoding the
    // image.
    //
    // Based on DM's get_decode_info() function.
    // https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.cpp#398
    SkString validateCanvasColorTypeAndGetDecodeInfo(SkImageInfo* decodeInfo,
                                                     SkColorType canvasColorType) {
        switch (fDstColorType) {
            case DstColorType::kForceGrayscale:
                if (kRGB_565_SkColorType == canvasColorType) {
                    return SkStringPrintf(
                            "canvas color type %s and destination color type %s are redundant",
                            sk_color_type_to_str(canvasColorType),
                            DstColorTypeToString(fDstColorType));
                }
                *decodeInfo = decodeInfo->makeColorType(kGray_8_SkColorType);
                break;

            case DstColorType::kForceNonNativePremulColor:
                if (kRGB_565_SkColorType == canvasColorType ||
                    kRGBA_F16_SkColorType == canvasColorType) {
                    return SkStringPrintf(
                            "canvas color type %s and destination color type %s are redundant",
                            sk_color_type_to_str(canvasColorType),
                            DstColorTypeToString(fDstColorType));
                }
#ifdef SK_PMCOLOR_IS_RGBA
                *decodeInfo = decodeInfo->makeColorType(kBGRA_8888_SkColorType);
#else
                *decodeInfo = decodeInfo->makeColorType(kRGBA_8888_SkColorType);
#endif
                break;

            case DstColorType::kGetFromCanvas:
                if (kRGB_565_SkColorType == canvasColorType &&
                    kOpaque_SkAlphaType != decodeInfo->alphaType()) {
                    return SkStringPrintf(
                            "image \"%s\" has alpha type %s; this is incompatible with with "
                            "canvas color type %s and destination color type %s",
                            fPath.c_str(),
                            sk_alpha_type_to_str(decodeInfo->alphaType()),
                            sk_color_type_to_str(canvasColorType),
                            DstColorTypeToString(fDstColorType));
                }
                *decodeInfo = decodeInfo->makeColorType(canvasColorType);
                break;

            default:
                SkUNREACHABLE;
        }

        *decodeInfo = decodeInfo->makeAlphaType(fDstAlphaType);
        return SkString();
    }

    // Based on DM's draw_to_canvas() function.
    // https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.cpp#432
    void drawToCanvas(SkCanvas* canvas,
                      const SkImageInfo& info,
                      void* pixels,
                      size_t rowBytes,
                      SkScalar left = 0,
                      SkScalar top = 0) {
        SkBitmap bitmap;
        bitmap.installPixels(info, pixels, rowBytes);
        swapRbIfNecessary(bitmap);
        canvas->drawImage(bitmap.asImage(), left, top);
    }

    // Allows us to test decodes to non-native 8888.
    //
    // Based on DM's swap_rb_if_necessary function.
    // https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DMSrcSink.cpp#387
    void swapRbIfNecessary(SkBitmap& bitmap) {
        if (DstColorType::kForceNonNativePremulColor != fDstColorType) {
            return;
        }

        for (int y = 0; y < bitmap.height(); y++) {
            uint32_t* row = (uint32_t*)bitmap.getAddr(0, y);
            SkOpts::RGBA_to_BGRA(row, row, bitmap.width());
        }
    }

    std::string fPath;
    DecodeMode fDecodeMode;
    DstColorType fDstColorType;
    SkAlphaType fDstAlphaType;
};

// Registers GMs with zero or more PNGCodecGM instances for the given image. Returns a non-empty,
// human-friendly error message in the case of errors.
//
// Based on DM's push_codec_srcs() function. It only covers "simple" codecs (lines 740-834).
// https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DM.cpp#740
//
// Specifically, this function does not capture any behaviors found in the following DM classes:
//
//  - AndroidCodecSrc
//  - BRDSrc
//  - ImageGenSrc
//
// TODO(lovisolo): Implement the above sources as GMs (if necessary).
static std::string registerGMsForImage(std::string path,
                                       PNGCodecGM::DecodeMode decodeMode,
                                       PNGCodecGM::DstColorType dstColorType,
                                       SkAlphaType dstAlphaType) {
    DecodeResult decodeResult = decode(path);
    if (decodeResult.errorMsg != "") {
        return decodeResult.errorMsg;
    }

    if (dstColorType == PNGCodecGM::DstColorType::kForceGrayscale &&
        decodeResult.codec->getInfo().colorType() != kGray_8_SkColorType) {
        return SkStringPrintf(
                       "image \"%s\" has color type %s; this is incompatible with the given "
                       "dstColorType argument: %s (expected image color type: %s)",
                       path.c_str(),
                       sk_color_type_to_str(decodeResult.codec->getInfo().colorType()),
                       PNGCodecGM::DstColorTypeToString(PNGCodecGM::DstColorType::kForceGrayscale),
                       sk_color_type_to_str(kGray_8_SkColorType))
                .c_str();
    }

    if (dstAlphaType == kUnpremul_SkAlphaType &&
        decodeResult.codec->getInfo().alphaType() == kOpaque_SkAlphaType) {
        return SkStringPrintf(
                       "image \"%s\" has alpha type %s; this is incompatible with the given "
                       "dstAlphaType argument: %s",
                       path.c_str(),
                       sk_alpha_type_to_str(kOpaque_SkAlphaType),
                       sk_alpha_type_to_str(kUnpremul_SkAlphaType))
                .c_str();
    }

    skiagm::Register(new PNGCodecGM(path, decodeMode, dstColorType, dstAlphaType));
    return "";
}

// Returns a non-empty message in the case of errors.
static std::string parse_and_validate_flags(PNGCodecGM::DecodeMode* decodeMode,
                                            PNGCodecGM::DstColorType* dstColorType,
                                            SkAlphaType* dstAlphaType) {
    skia_private::THashMap<SkString, PNGCodecGM::DecodeMode> decodeModeValues = {
            {SkString("get-all-pixels"), PNGCodecGM::DecodeMode::kGetAllPixels},
            {SkString("incremental"), PNGCodecGM::DecodeMode::kIncremental},
            {SkString("zero-init"), PNGCodecGM::DecodeMode::kZeroInit},
    };
    if (SkString errorMsg = FLAGS_pngCodecDecodeMode.parseAndValidate(
                "--pngCodecDecodeMode", decodeModeValues, decodeMode);
        errorMsg != SkString()) {
        return errorMsg.c_str();
    }

    skia_private::THashMap<SkString, PNGCodecGM::DstColorType> dstColorTypeValues = {
            {SkString("get-from-canvas"), PNGCodecGM::DstColorType::kGetFromCanvas},
            {SkString("force-grayscale"), PNGCodecGM::DstColorType::kForceGrayscale},
            {SkString("force-nonnative-premul-color"),
             PNGCodecGM::DstColorType::kForceNonNativePremulColor},
    };
    if (SkString errorMsg = FLAGS_pngCodecDstColorType.parseAndValidate(
                "--pngCodecDstColorType", dstColorTypeValues, dstColorType);
        errorMsg != SkString()) {
        return errorMsg.c_str();
    }

    skia_private::THashMap<SkString, SkAlphaType> dstAlphaTypeValues = {
            {SkString("premul"), kPremul_SkAlphaType},
            {SkString("unpremul"), kUnpremul_SkAlphaType},
    };
    if (SkString errorMsg = FLAGS_pngCodecDstAlphaType.parseAndValidate(
                "--pngCodecDstAlphaType", dstAlphaTypeValues, dstAlphaType);
        errorMsg != SkString()) {
        return errorMsg.c_str();
    }

    return "";
}

// Registers one PNGCodecGM instance for each image passed via the --pngCodecGMImages flag, which
// can take files and directories. Directories are scanned non-recursively.
//
// Based on DM's gather_srcs() function.
// https://skia.googlesource.com/skia/+/ce49fc71bc7cc25244020cd3e64764a6d08e54fb/dm/DM.cpp#953
DEF_GM_REGISTERER_FN([]() -> std::string {
    // Parse flags.
    PNGCodecGM::DecodeMode decodeMode;
    PNGCodecGM::DstColorType dstColorType;
    SkAlphaType dstAlphaType;
    if (std::string errorMsg = parse_and_validate_flags(&decodeMode, &dstColorType, &dstAlphaType);
        errorMsg != "") {
        return errorMsg;
    }

    // Collect images.
    skia_private::TArray<SkString> images;
    if (!CommonFlags::CollectImages(FLAGS_pngCodecGMImages, &images)) {
        return "Failed to collect images.";
    }

    // Register one GM per image.
    for (const SkString& image : images) {
        if (std::string errorMsg =
                    registerGMsForImage(image.c_str(), decodeMode, dstColorType, dstAlphaType);
            errorMsg != "") {
            return errorMsg;
        }
    }

    return "";
});
