/*
 * Copyright 2022 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <ultrahdr/jpegrutils.h>

#include <algorithm>
#include <cmath>

#include <image_io/xml/xml_reader.h>
#include <image_io/xml/xml_writer.h>
#include <image_io/base/message_handler.h>
#include <image_io/xml/xml_element_rules.h>
#include <image_io/xml/xml_handler.h>
#include <image_io/xml/xml_rule.h>
#include <utils/Log.h>

using namespace photos_editing_formats::image_io;
using namespace std;

namespace android::ultrahdr {
/*
 * Helper function used for generating XMP metadata.
 *
 * @param prefix The prefix part of the name.
 * @param suffix The suffix part of the name.
 * @return A name of the form "prefix:suffix".
 */
static inline string Name(const string &prefix, const string &suffix) {
  std::stringstream ss;
  ss << prefix << ":" << suffix;
  return ss.str();
}

DataStruct::DataStruct(int s) {
    data = malloc(s);
    length = s;
    memset(data, 0, s);
    writePos = 0;
}

DataStruct::~DataStruct() {
    if (data != nullptr) {
        free(data);
    }
}

void* DataStruct::getData() {
    return data;
}

int DataStruct::getLength() {
    return length;
}

int DataStruct::getBytesWritten() {
    return writePos;
}

bool DataStruct::write8(uint8_t value) {
    uint8_t v = value;
    return write(&v, 1);
}

bool DataStruct::write16(uint16_t value) {
    uint16_t v = value;
    return write(&v, 2);
}
bool DataStruct::write32(uint32_t value) {
    uint32_t v = value;
    return write(&v, 4);
}

bool DataStruct::write(const void* src, int size) {
    if (writePos + size > length) {
        ALOGE("Writing out of boundary: write position: %d, size: %d, capacity: %d",
                writePos, size, length);
        return false;
    }
    memcpy((uint8_t*) data + writePos, src, size);
    writePos += size;
    return true;
}

/*
 * Helper function used for writing data to destination.
 */
status_t Write(jr_compressed_ptr destination, const void* source, size_t length, int &position) {
  if (position + length > destination->maxLength) {
    return ERROR_JPEGR_BUFFER_TOO_SMALL;
  }

  memcpy((uint8_t*)destination->data + sizeof(uint8_t) * position, source, length);
  position += length;
  return NO_ERROR;
}

// Extremely simple XML Handler - just searches for interesting elements
class XMPXmlHandler : public XmlHandler {
public:

    XMPXmlHandler() : XmlHandler() {
        state = NotStrarted;
        versionFound = false;
        minContentBoostFound = false;
        maxContentBoostFound = false;
        gammaFound = false;
        offsetSdrFound = false;
        offsetHdrFound = false;
        hdrCapacityMinFound = false;
        hdrCapacityMaxFound = false;
        baseRenditionIsHdrFound = false;
    }

    enum ParseState {
        NotStrarted,
        Started,
        Done
    };

    virtual DataMatchResult StartElement(const XmlTokenContext& context) {
        string val;
        if (context.BuildTokenValue(&val)) {
            if (!val.compare(containerName)) {
                state = Started;
            } else {
                if (state != Done) {
                    state = NotStrarted;
                }
            }
        }
        return context.GetResult();
    }

    virtual DataMatchResult FinishElement(const XmlTokenContext& context) {
        if (state == Started) {
            state = Done;
            lastAttributeName = "";
        }
        return context.GetResult();
    }

    virtual DataMatchResult AttributeName(const XmlTokenContext& context) {
        string val;
        if (state == Started) {
            if (context.BuildTokenValue(&val)) {
                if (!val.compare(versionAttrName)) {
                    lastAttributeName = versionAttrName;
                } else if (!val.compare(maxContentBoostAttrName)) {
                    lastAttributeName = maxContentBoostAttrName;
                } else if (!val.compare(minContentBoostAttrName)) {
                    lastAttributeName = minContentBoostAttrName;
                } else if (!val.compare(gammaAttrName)) {
                    lastAttributeName = gammaAttrName;
                } else if (!val.compare(offsetSdrAttrName)) {
                    lastAttributeName = offsetSdrAttrName;
                } else if (!val.compare(offsetHdrAttrName)) {
                    lastAttributeName = offsetHdrAttrName;
                } else if (!val.compare(hdrCapacityMinAttrName)) {
                    lastAttributeName = hdrCapacityMinAttrName;
                } else if (!val.compare(hdrCapacityMaxAttrName)) {
                    lastAttributeName = hdrCapacityMaxAttrName;
                } else if (!val.compare(baseRenditionIsHdrAttrName)) {
                    lastAttributeName = baseRenditionIsHdrAttrName;
                } else {
                    lastAttributeName = "";
                }
            }
        }
        return context.GetResult();
    }

    virtual DataMatchResult AttributeValue(const XmlTokenContext& context) {
        string val;
        if (state == Started) {
            if (context.BuildTokenValue(&val, true)) {
                if (!lastAttributeName.compare(versionAttrName)) {
                    versionStr = val;
                    versionFound = true;
                } else if (!lastAttributeName.compare(maxContentBoostAttrName)) {
                    maxContentBoostStr = val;
                    maxContentBoostFound = true;
                } else if (!lastAttributeName.compare(minContentBoostAttrName)) {
                    minContentBoostStr = val;
                    minContentBoostFound = true;
                } else if (!lastAttributeName.compare(gammaAttrName)) {
                    gammaStr = val;
                    gammaFound = true;
                } else if (!lastAttributeName.compare(offsetSdrAttrName)) {
                    offsetSdrStr = val;
                    offsetSdrFound = true;
                } else if (!lastAttributeName.compare(offsetHdrAttrName)) {
                    offsetHdrStr = val;
                    offsetHdrFound = true;
                } else if (!lastAttributeName.compare(hdrCapacityMinAttrName)) {
                    hdrCapacityMinStr = val;
                    hdrCapacityMinFound = true;
                } else if (!lastAttributeName.compare(hdrCapacityMaxAttrName)) {
                    hdrCapacityMaxStr = val;
                    hdrCapacityMaxFound = true;
                } else if (!lastAttributeName.compare(baseRenditionIsHdrAttrName)) {
                    baseRenditionIsHdrStr = val;
                    baseRenditionIsHdrFound = true;
                }
            }
        }
        return context.GetResult();
    }

    bool getVersion(string* version, bool* present) {
        if (state == Done) {
            *version = versionStr;
            *present = versionFound;
            return true;
        } else {
            return false;
        }
    }

    bool getMaxContentBoost(float* max_content_boost, bool* present) {
        if (state == Done) {
            *present = maxContentBoostFound;
            stringstream ss(maxContentBoostStr);
            float val;
            if (ss >> val) {
                *max_content_boost = exp2(val);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    bool getMinContentBoost(float* min_content_boost, bool* present) {
        if (state == Done) {
            *present = minContentBoostFound;
            stringstream ss(minContentBoostStr);
            float val;
            if (ss >> val) {
                *min_content_boost = exp2(val);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    bool getGamma(float* gamma, bool* present) {
        if (state == Done) {
            *present = gammaFound;
            stringstream ss(gammaStr);
            float val;
            if (ss >> val) {
                *gamma = val;
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    bool getOffsetSdr(float* offset_sdr, bool* present) {
        if (state == Done) {
            *present = offsetSdrFound;
            stringstream ss(offsetSdrStr);
            float val;
            if (ss >> val) {
                *offset_sdr = val;
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    bool getOffsetHdr(float* offset_hdr, bool* present) {
        if (state == Done) {
            *present = offsetHdrFound;
            stringstream ss(offsetHdrStr);
            float val;
            if (ss >> val) {
                *offset_hdr = val;
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    bool getHdrCapacityMin(float* hdr_capacity_min, bool* present) {
        if (state == Done) {
            *present = hdrCapacityMinFound;
            stringstream ss(hdrCapacityMinStr);
            float val;
            if (ss >> val) {
                *hdr_capacity_min = exp2(val);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    bool getHdrCapacityMax(float* hdr_capacity_max, bool* present) {
        if (state == Done) {
            *present = hdrCapacityMaxFound;
            stringstream ss(hdrCapacityMaxStr);
            float val;
            if (ss >> val) {
                *hdr_capacity_max = exp2(val);
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    bool getBaseRenditionIsHdr(bool* base_rendition_is_hdr, bool* present) {
        if (state == Done) {
            *present = baseRenditionIsHdrFound;
            if (!baseRenditionIsHdrStr.compare("False")) {
                *base_rendition_is_hdr = false;
                return true;
            } else if (!baseRenditionIsHdrStr.compare("True")) {
                *base_rendition_is_hdr = true;
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }



private:
    static const string containerName;

    static const string versionAttrName;
    string              versionStr;
    bool                versionFound;
    static const string maxContentBoostAttrName;
    string              maxContentBoostStr;
    bool                maxContentBoostFound;
    static const string minContentBoostAttrName;
    string              minContentBoostStr;
    bool                minContentBoostFound;
    static const string gammaAttrName;
    string              gammaStr;
    bool                gammaFound;
    static const string offsetSdrAttrName;
    string              offsetSdrStr;
    bool                offsetSdrFound;
    static const string offsetHdrAttrName;
    string              offsetHdrStr;
    bool                offsetHdrFound;
    static const string hdrCapacityMinAttrName;
    string              hdrCapacityMinStr;
    bool                hdrCapacityMinFound;
    static const string hdrCapacityMaxAttrName;
    string              hdrCapacityMaxStr;
    bool                hdrCapacityMaxFound;
    static const string baseRenditionIsHdrAttrName;
    string              baseRenditionIsHdrStr;
    bool                baseRenditionIsHdrFound;

    string              lastAttributeName;
    ParseState          state;
};

// GContainer XMP constants - URI and namespace prefix
const string kContainerUri        = "http://ns.google.com/photos/1.0/container/";
const string kContainerPrefix     = "Container";

// GContainer XMP constants - element and attribute names
const string kConDirectory            = Name(kContainerPrefix, "Directory");
const string kConItem                 = Name(kContainerPrefix, "Item");

// GContainer XMP constants - names for XMP handlers
const string XMPXmlHandler::containerName = "rdf:Description";
// Item XMP constants - URI and namespace prefix
const string kItemUri        = "http://ns.google.com/photos/1.0/container/item/";
const string kItemPrefix     = "Item";

// Item XMP constants - element and attribute names
const string kItemLength           = Name(kItemPrefix, "Length");
const string kItemMime             = Name(kItemPrefix, "Mime");
const string kItemSemantic         = Name(kItemPrefix, "Semantic");

// Item XMP constants - element and attribute values
const string kSemanticPrimary = "Primary";
const string kSemanticGainMap = "GainMap";
const string kMimeImageJpeg   = "image/jpeg";

// GainMap XMP constants - URI and namespace prefix
const string kGainMapUri      = "http://ns.adobe.com/hdr-gain-map/1.0/";
const string kGainMapPrefix   = "hdrgm";

// GainMap XMP constants - element and attribute names
const string kMapVersion            = Name(kGainMapPrefix, "Version");
const string kMapGainMapMin         = Name(kGainMapPrefix, "GainMapMin");
const string kMapGainMapMax         = Name(kGainMapPrefix, "GainMapMax");
const string kMapGamma              = Name(kGainMapPrefix, "Gamma");
const string kMapOffsetSdr          = Name(kGainMapPrefix, "OffsetSDR");
const string kMapOffsetHdr          = Name(kGainMapPrefix, "OffsetHDR");
const string kMapHDRCapacityMin     = Name(kGainMapPrefix, "HDRCapacityMin");
const string kMapHDRCapacityMax     = Name(kGainMapPrefix, "HDRCapacityMax");
const string kMapBaseRenditionIsHDR = Name(kGainMapPrefix, "BaseRenditionIsHDR");

// GainMap XMP constants - names for XMP handlers
const string XMPXmlHandler::versionAttrName = kMapVersion;
const string XMPXmlHandler::minContentBoostAttrName = kMapGainMapMin;
const string XMPXmlHandler::maxContentBoostAttrName = kMapGainMapMax;
const string XMPXmlHandler::gammaAttrName = kMapGamma;
const string XMPXmlHandler::offsetSdrAttrName = kMapOffsetSdr;
const string XMPXmlHandler::offsetHdrAttrName = kMapOffsetHdr;
const string XMPXmlHandler::hdrCapacityMinAttrName = kMapHDRCapacityMin;
const string XMPXmlHandler::hdrCapacityMaxAttrName = kMapHDRCapacityMax;
const string XMPXmlHandler::baseRenditionIsHdrAttrName = kMapBaseRenditionIsHDR;

bool getMetadataFromXMP(uint8_t* xmp_data, size_t xmp_size, ultrahdr_metadata_struct* metadata) {
    string nameSpace = "http://ns.adobe.com/xap/1.0/\0";

    if (xmp_size < nameSpace.size()+2) {
        // Data too short
        return false;
    }

    if (strncmp(reinterpret_cast<char*>(xmp_data), nameSpace.c_str(), nameSpace.size())) {
        // Not correct namespace
        return false;
    }

    // Position the pointers to the start of XMP XML portion
    xmp_data += nameSpace.size()+1;
    xmp_size -= nameSpace.size()+1;
    XMPXmlHandler handler;

    // We need to remove tail data until the closing tag. Otherwise parser will throw an error.
    while(xmp_data[xmp_size-1]!='>' && xmp_size > 1) {
        xmp_size--;
    }

    string str(reinterpret_cast<const char*>(xmp_data), xmp_size);
    MessageHandler msg_handler;
    unique_ptr<XmlRule> rule(new XmlElementRule);
    XmlReader reader(&handler, &msg_handler);
    reader.StartParse(std::move(rule));
    reader.Parse(str);
    reader.FinishParse();
    if (reader.HasErrors()) {
        // Parse error
        return false;
    }

    // Apply default values to any not-present fields, except for Version,
    // maxContentBoost, and hdrCapacityMax, which are required. Return false if
    // we encounter a present field that couldn't be parsed, since this
    // indicates it is invalid (eg. string where there should be a float).
    bool present = false;
    if (!handler.getVersion(&metadata->version, &present) || !present) {
        return false;
    }
    if (!handler.getMaxContentBoost(&metadata->maxContentBoost, &present) || !present) {
        return false;
    }
    if (!handler.getHdrCapacityMax(&metadata->hdrCapacityMax, &present) || !present) {
        return false;
    }
    if (!handler.getMinContentBoost(&metadata->minContentBoost, &present)) {
        if (present) return false;
        metadata->minContentBoost = 1.0f;
    }
    if (!handler.getGamma(&metadata->gamma, &present)) {
        if (present) return false;
        metadata->gamma = 1.0f;
    }
    if (!handler.getOffsetSdr(&metadata->offsetSdr, &present)) {
        if (present) return false;
        metadata->offsetSdr = 1.0f / 64.0f;
    }
    if (!handler.getOffsetHdr(&metadata->offsetHdr, &present)) {
        if (present) return false;
        metadata->offsetHdr = 1.0f / 64.0f;
    }
    if (!handler.getHdrCapacityMin(&metadata->hdrCapacityMin, &present)) {
        if (present) return false;
        metadata->hdrCapacityMin = 1.0f;
    }

    bool base_rendition_is_hdr;
    if (!handler.getBaseRenditionIsHdr(&base_rendition_is_hdr, &present)) {
        if (present) return false;
        base_rendition_is_hdr = false;
    }
    if (base_rendition_is_hdr) {
        ALOGE("Base rendition of HDR is not supported!");
        return false;
    }

    return true;
}

string generateXmpForPrimaryImage(int secondary_image_length, ultrahdr_metadata_struct& metadata) {
  const vector<string> kConDirSeq({kConDirectory, string("rdf:Seq")});
  const vector<string> kLiItem({string("rdf:li"), kConItem});

  std::stringstream ss;
  photos_editing_formats::image_io::XmlWriter writer(ss);
  writer.StartWritingElement("x:xmpmeta");
  writer.WriteXmlns("x", "adobe:ns:meta/");
  writer.WriteAttributeNameAndValue("x:xmptk", "Adobe XMP Core 5.1.2");
  writer.StartWritingElement("rdf:RDF");
  writer.WriteXmlns("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
  writer.StartWritingElement("rdf:Description");
  writer.WriteXmlns(kContainerPrefix, kContainerUri);
  writer.WriteXmlns(kItemPrefix, kItemUri);
  writer.WriteXmlns(kGainMapPrefix, kGainMapUri);
  writer.WriteAttributeNameAndValue(kMapVersion, metadata.version);

  writer.StartWritingElements(kConDirSeq);

  size_t item_depth = writer.StartWritingElement("rdf:li");
  writer.WriteAttributeNameAndValue("rdf:parseType", "Resource");
  writer.StartWritingElement(kConItem);
  writer.WriteAttributeNameAndValue(kItemSemantic, kSemanticPrimary);
  writer.WriteAttributeNameAndValue(kItemMime, kMimeImageJpeg);
  writer.FinishWritingElementsToDepth(item_depth);

  writer.StartWritingElement("rdf:li");
  writer.WriteAttributeNameAndValue("rdf:parseType", "Resource");
  writer.StartWritingElement(kConItem);
  writer.WriteAttributeNameAndValue(kItemSemantic, kSemanticGainMap);
  writer.WriteAttributeNameAndValue(kItemMime, kMimeImageJpeg);
  writer.WriteAttributeNameAndValue(kItemLength, secondary_image_length);

  writer.FinishWriting();

  return ss.str();
}

string generateXmpForSecondaryImage(ultrahdr_metadata_struct& metadata) {
  const vector<string> kConDirSeq({kConDirectory, string("rdf:Seq")});

  std::stringstream ss;
  photos_editing_formats::image_io::XmlWriter writer(ss);
  writer.StartWritingElement("x:xmpmeta");
  writer.WriteXmlns("x", "adobe:ns:meta/");
  writer.WriteAttributeNameAndValue("x:xmptk", "Adobe XMP Core 5.1.2");
  writer.StartWritingElement("rdf:RDF");
  writer.WriteXmlns("rdf", "http://www.w3.org/1999/02/22-rdf-syntax-ns#");
  writer.StartWritingElement("rdf:Description");
  writer.WriteXmlns(kGainMapPrefix, kGainMapUri);
  writer.WriteAttributeNameAndValue(kMapVersion, metadata.version);
  writer.WriteAttributeNameAndValue(kMapGainMapMin, log2(metadata.minContentBoost));
  writer.WriteAttributeNameAndValue(kMapGainMapMax, log2(metadata.maxContentBoost));
  writer.WriteAttributeNameAndValue(kMapGamma, metadata.gamma);
  writer.WriteAttributeNameAndValue(kMapOffsetSdr, metadata.offsetSdr);
  writer.WriteAttributeNameAndValue(kMapOffsetHdr, metadata.offsetHdr);
  writer.WriteAttributeNameAndValue(kMapHDRCapacityMin, log2(metadata.hdrCapacityMin));
  writer.WriteAttributeNameAndValue(kMapHDRCapacityMax, log2(metadata.hdrCapacityMax));
  writer.WriteAttributeNameAndValue(kMapBaseRenditionIsHDR, "False");
  writer.FinishWriting();

  return ss.str();
}

} // namespace android::ultrahdr
