/*
 * 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 "include/core/SkData.h"
#include "include/private/SkGainmapInfo.h"
#include "src/codec/SkJpegXmp.h"
#include "src/core/SkMD5.h"
#include "tests/Test.h"

#include <iomanip>
#include <iostream>
#include <regex>
#include <sstream>

DEF_TEST(SkJpegXmp_standardXmp, r) {
    const char xmpData[] =
            "http://ns.adobe.com/xap/1.0/\0"
            R"(
            <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
               <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                        xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/">
                  <rdf:Description rdf:about="">
                     <hdrgm:Version>1.0</hdrgm:Version>
                     <hdrgm:GainMapMax>3</hdrgm:GainMapMax>
                     <hdrgm:HDRCapacityMax>4</hdrgm:HDRCapacityMax>
                  </rdf:Description>
               </rdf:RDF>
            </x:xmpmeta>)";

    std::vector<sk_sp<const SkData>> app1Params;
    app1Params.push_back(SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1));

    auto xmp = SkJpegMakeXmp(app1Params);
    REPORTER_ASSERT(r, xmp);

    SkGainmapInfo info;
    REPORTER_ASSERT(r, xmp->getGainmapInfoHDRGM(&info));
    REPORTER_ASSERT(r, info.fGainmapRatioMax.fR == 8.f);
    REPORTER_ASSERT(r, info.fDisplayRatioHdr == 16.f);
}

DEF_TEST(SkJpegXmp_defaultValues, r) {
    const char xmpData[] =
            "http://ns.adobe.com/xap/1.0/\0"
            R"(
            <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
               <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                        xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/">
                  <rdf:Description rdf:about="" hdrgm:Version="1.0">
                  </rdf:Description>
               </rdf:RDF>
            </x:xmpmeta>)";

    std::vector<sk_sp<const SkData>> app1Params;
    app1Params.push_back(SkData::MakeWithoutCopy(xmpData, sizeof(xmpData) - 1));

    auto xmp = SkJpegMakeXmp(app1Params);
    REPORTER_ASSERT(r, xmp);

    SkGainmapInfo info;
    REPORTER_ASSERT(r, xmp->getGainmapInfoHDRGM(&info));
    REPORTER_ASSERT(r, info.fGainmapRatioMin.fR == 1.f);
    REPORTER_ASSERT(r, info.fGainmapRatioMin.fG == 1.f);
    REPORTER_ASSERT(r, info.fGainmapRatioMin.fB == 1.f);
    REPORTER_ASSERT(r, info.fGainmapRatioMax.fR == 2.f);
    REPORTER_ASSERT(r, info.fGainmapRatioMax.fG == 2.f);
    REPORTER_ASSERT(r, info.fGainmapRatioMax.fB == 2.f);
    REPORTER_ASSERT(r, info.fGainmapGamma.fR == 1.f);
    REPORTER_ASSERT(r, info.fGainmapGamma.fG == 1.f);
    REPORTER_ASSERT(r, info.fGainmapGamma.fB == 1.f);
    REPORTER_ASSERT(r, info.fEpsilonSdr.fR == 1.f / 64.f);
    REPORTER_ASSERT(r, info.fEpsilonSdr.fG == 1.f / 64.f);
    REPORTER_ASSERT(r, info.fEpsilonSdr.fB == 1.f / 64.f);
    REPORTER_ASSERT(r, info.fEpsilonHdr.fG == 1.f / 64.f);
    REPORTER_ASSERT(r, info.fEpsilonHdr.fR == 1.f / 64.f);
    REPORTER_ASSERT(r, info.fEpsilonHdr.fB == 1.f / 64.f);
    REPORTER_ASSERT(r, info.fDisplayRatioSdr == 1.f);
    REPORTER_ASSERT(r, info.fDisplayRatioHdr == 2.f);
}

static std::string uint32_to_string(uint32_t v) {
    const char c[4] = {static_cast<char>((v >> 24) & 0xff),
                       static_cast<char>((v >> 16) & 0xff),
                       static_cast<char>((v >> 8) & 0xff),
                       static_cast<char>(v & 0xff)};
    return std::string(c, 4);
}

static std::string standard_xmp_with_header(const SkMD5::Digest& digest, const std::string& data) {
    const std::string guid = digest.toHexString().c_str();
    const std::string dataWithGuid = std::regex_replace(data, std::regex("\\$GUID"), guid);
    return std::string("http://ns.adobe.com/xap/1.0/") + '\0' + dataWithGuid;
}

static std::string extended_xmp_with_header(const SkMD5::Digest& digest,
                                            uint32_t size,
                                            uint32_t offset,
                                            const std::string& data) {
    return std::string("http://ns.adobe.com/xmp/extension/") + '\0' + digest.toHexString().c_str() +
           uint32_to_string(size) + uint32_to_string(offset) + data;
}

DEF_TEST(SkJpegXmp_readExtendedXmp, r) {
    const std::string standardXmpData = R"(
            <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
               <rdf:RDF xmlns:xmpNote="http://ns.adobe.com/xmp/note/">
                  <rdf:Description rdf:about="">
                     <xmpNote:HasExtendedXMP>$GUID</xmpNote:HasExtendedXMP>
                  </rdf:Description>
               </rdf:RDF>
            </x:xmpmeta>)";

    const std::string extendedXmpData1 = R"(
        <x:xmpmeta xmlns:x="adobe:ns:meta/" x:xmptk="XMP Core 6.0.0">
            <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
                    xmlns:hdrgm="http://ns.adobe.com/hdr-gain-map/1.0/">
                <rdf:Description rdf:about="">
                     <hdrgm:Version>1.0</hdrgm:Version>
                     <hdrgm:GainMapMax>3</hdrgm:GainMapMax>
                    <hdrgm:HDRCapacityMax>4</hdrgm:HDRCapacityMax>)";
    const std::string extendedXmpData2 = R"(
                </rdf:Description>
            </rdf:RDF>
        </x:xmpmeta>)";

    const uint32_t totalExtendedXmpSize = extendedXmpData1.size() + extendedXmpData2.size();
    SkMD5 md5;
    md5.write(extendedXmpData1.data(), extendedXmpData1.length());
    md5.write(extendedXmpData2.data(), extendedXmpData2.length());
    const SkMD5::Digest digest = md5.finish();

    const std::string standardXmpDataWithHeader = standard_xmp_with_header(digest, standardXmpData);

    const uint32_t offset1 = 0;
    const std::string extendedXmpData1WithHeader =
            extended_xmp_with_header(digest, totalExtendedXmpSize, offset1, extendedXmpData1);

    const uint32_t offset2 = extendedXmpData1.size();
    const std::string extendedXmpData2WithHeader =
            extended_xmp_with_header(digest, totalExtendedXmpSize, offset2, extendedXmpData2);

    std::vector<sk_sp<const SkData>> app1Params;
    app1Params.push_back(SkData::MakeWithoutCopy(standardXmpDataWithHeader.data(),
                                                 standardXmpDataWithHeader.length()));
    app1Params.push_back(SkData::MakeWithoutCopy(extendedXmpData1WithHeader.data(),
                                                 extendedXmpData1WithHeader.length()));
    app1Params.push_back(SkData::MakeWithoutCopy(extendedXmpData2WithHeader.data(),
                                                 extendedXmpData2WithHeader.length()));

    auto xmp = SkJpegMakeXmp(app1Params);
    REPORTER_ASSERT(r, xmp);

    SkGainmapInfo info;
    REPORTER_ASSERT(r, xmp->getGainmapInfoHDRGM(&info));
    REPORTER_ASSERT(r, info.fGainmapRatioMax.fR == 8.f);
    REPORTER_ASSERT(r, info.fDisplayRatioHdr == 16.f);
}
