// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../include/fpdfdoc/fpdf_doc.h"
#include "../../include/fxcrt/fx_xml.h"
typedef struct _PDFDOC_METADATA {
    CPDF_Document *m_pDoc;
    CXML_Element *m_pXmlElmnt;
    CXML_Element *m_pElmntRdf;
    CFX_CMapByteStringToPtr *m_pStringMap;
} PDFDOC_METADATA, * PDFDOC_LPMETADATA;
typedef PDFDOC_METADATA const * PDFDOC_LPCMETADATA;
const FX_CHAR* const gs_FPDFDOC_Metadata_Titles[] = {
    "Title", "title",
    "Subject", "description",
    "Author", "creator",
    "Keywords", "Keywords",
    "Producer", "Producer",
    "Creator", "CreatorTool",
    "CreationDate", "CreateDate",
    "ModDate", "ModifyDate",
    "MetadataDate", "MetadataDate"
};
CPDF_Metadata::CPDF_Metadata()
{
    m_pData = FX_Alloc(PDFDOC_METADATA, 1);
    CFX_CMapByteStringToPtr *&pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
    pStringMap = FX_NEW CFX_CMapByteStringToPtr;
    if (pStringMap != NULL) {
        CFX_ByteString bstr;
        for (int i = 0; i < 18; i += 2) {
            bstr = gs_FPDFDOC_Metadata_Titles[i];
            pStringMap->AddValue(bstr, (void*)gs_FPDFDOC_Metadata_Titles[i + 1]);
        }
    }
}
CPDF_Metadata::~CPDF_Metadata()
{
    FXSYS_assert(m_pData != NULL);
    CXML_Element *&p = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
    delete p;
    CFX_CMapByteStringToPtr *pStringMap = ((PDFDOC_LPMETADATA)m_pData)->m_pStringMap;
    if (pStringMap) {
        pStringMap->RemoveAll();
        delete pStringMap;
    }
    FX_Free(m_pData);
}
void CPDF_Metadata::LoadDoc(CPDF_Document *pDoc)
{
    FXSYS_assert(pDoc != NULL);
    ((PDFDOC_LPMETADATA)m_pData)->m_pDoc = pDoc;
    CPDF_Dictionary *pRoot = pDoc->GetRoot();
    CPDF_Stream *pStream = pRoot->GetStream(FX_BSTRC("Metadata"));
    if (!pStream) {
        return;
    }
    CPDF_StreamAcc acc;
    acc.LoadAllData(pStream, FALSE);
    int size = acc.GetSize();
    const uint8_t* pBuf = acc.GetData();
    CXML_Element *&pXmlElmnt = ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
    pXmlElmnt = CXML_Element::Parse(pBuf, size);
    if (!pXmlElmnt) {
        return;
    }
    CXML_Element *&pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
    if (pXmlElmnt->GetTagName() == FX_BSTRC("RDF")) {
        pElmntRdf = pXmlElmnt;
    } else {
        pElmntRdf = pXmlElmnt->GetElement(NULL, FX_BSTRC("RDF"));
    }
}
int32_t CPDF_Metadata::GetString(const CFX_ByteStringC& bsItem, CFX_WideString &wsStr)
{
    if (!((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt) {
        return -1;
    }
    if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap) {
        return -1;
    }
    void *szTag;
    if (!((PDFDOC_LPMETADATA)m_pData)->m_pStringMap->Lookup(bsItem, szTag)) {
        return -1;
    }
    CFX_ByteString bsTag = (const FX_CHAR*)szTag;
    wsStr = L"";
    CXML_Element *pElmntRdf = ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
    if (!pElmntRdf) {
        return -1;
    }
    int nChild = pElmntRdf->CountChildren();
    for (int i = 0; i < nChild; i++) {
        CXML_Element *pTag = pElmntRdf->GetElement(NULL, FX_BSTRC("Description"), i);
        if (!pTag) {
            continue;
        }
        if (bsItem == FX_BSTRC("Title") || bsItem == FX_BSTRC("Subject")) {
            CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
            if (!pElmnt) {
                continue;
            }
            pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Alt"));
            if (!pElmnt) {
                continue;
            }
            pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
            if (!pElmnt) {
                continue;
            }
            wsStr = pElmnt->GetContent(0);
            return wsStr.GetLength();
        } else if (bsItem == FX_BSTRC("Author")) {
            CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
            if (!pElmnt) {
                continue;
            }
            pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("Seq"));
            if (!pElmnt) {
                continue;
            }
            pElmnt = pElmnt->GetElement(NULL, FX_BSTRC("li"));
            if (!pElmnt) {
                continue;
            }
            wsStr = pElmnt->GetContent(0);
            return wsStr.GetLength();
        } else {
            CXML_Element *pElmnt = pTag->GetElement(NULL, bsTag);
            if (!pElmnt) {
                continue;
            }
            wsStr = pElmnt->GetContent(0);
            return wsStr.GetLength();
        }
    }
    return -1;
}
CXML_Element* CPDF_Metadata::GetRoot() const
{
    return ((PDFDOC_LPMETADATA)m_pData)->m_pXmlElmnt;
}
CXML_Element* CPDF_Metadata::GetRDF() const
{
    return ((PDFDOC_LPMETADATA)m_pData)->m_pElmntRdf;
}
