// 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 = new CFX_CMapByteStringToPtr;
    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();
        }
        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();
        }
        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;
}
