// 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 "../../public/fpdf_ppo.h"
#include "../../third_party/base/nonstd_unique_ptr.h"
#include "../include/fsdk_define.h"

class CPDF_PageOrganizer
{
public:
    using ObjectNumberMap = std::map<FX_DWORD, FX_DWORD>;
    CPDF_PageOrganizer();
    ~CPDF_PageOrganizer();

    bool PDFDocInit(CPDF_Document* pDestPDFDoc, CPDF_Document* pSrcPDFDoc);
    bool ExportPage(CPDF_Document* pSrcPDFDoc,
                       CFX_WordArray* nPageNum,
                       CPDF_Document* pDestPDFDoc,
                       int nIndex);
    CPDF_Object* PageDictGetInheritableTag(CPDF_Dictionary* pDict,
                                           CFX_ByteString nSrctag);
    bool UpdateReference(CPDF_Object* pObj,
                            CPDF_Document* pDoc,
                            ObjectNumberMap* pObjNumberMap);
    FX_DWORD GetNewObjId(CPDF_Document* pDoc,
                         ObjectNumberMap* pObjNumberMap,
                         CPDF_Reference* pRef);
};


CPDF_PageOrganizer::CPDF_PageOrganizer()
{
}

CPDF_PageOrganizer::~CPDF_PageOrganizer()
{
}

bool CPDF_PageOrganizer::PDFDocInit(CPDF_Document* pDestPDFDoc,
                                       CPDF_Document* pSrcPDFDoc)
{
    if (!pDestPDFDoc || !pSrcPDFDoc)
        return false;

    CPDF_Dictionary* pNewRoot = pDestPDFDoc->GetRoot();
    if (!pNewRoot)
        return false;

    //Set the document information////////////////////////////////////////////

    CPDF_Dictionary* DInfoDict = pDestPDFDoc->GetInfo();
    if (!DInfoDict)
        return false;

    CFX_ByteString producerstr;
    producerstr.Format("PDFium");
    DInfoDict->SetAt("Producer", new CPDF_String(producerstr));

    //Set type////////////////////////////////////////////////////////////////
    CFX_ByteString cbRootType = pNewRoot->GetString("Type", "");
    if (cbRootType.Equal("") ) {
        pNewRoot->SetAt("Type", new CPDF_Name("Catalog"));
    }

    CPDF_Object* pElement = pNewRoot->GetElement("Pages");
    CPDF_Dictionary* pNewPages = pElement ?
        (CPDF_Dictionary*)pElement->GetDirect() : nullptr;
    if (!pNewPages) {
        pNewPages = new CPDF_Dictionary;
        FX_DWORD NewPagesON = pDestPDFDoc->AddIndirectObject(pNewPages);
        pNewRoot->SetAt("Pages", new CPDF_Reference(pDestPDFDoc, NewPagesON));
    }

    CFX_ByteString cbPageType = pNewPages->GetString("Type", "");
    if (cbPageType.Equal("")) {
        pNewPages->SetAt("Type", new CPDF_Name("Pages"));
    }

    CPDF_Array* pKeysArray = pNewPages->GetArray("Kids");
    if (!pKeysArray) {
        CPDF_Array* pNewKids = new CPDF_Array;
        FX_DWORD Kidsobjnum = -1;
        Kidsobjnum = pDestPDFDoc->AddIndirectObject(pNewKids);

        pNewPages->SetAt("Kids", new CPDF_Reference(pDestPDFDoc, Kidsobjnum));
        pNewPages->SetAt("Count", new CPDF_Number(0));
    }

    return true;
}

bool CPDF_PageOrganizer::ExportPage(CPDF_Document* pSrcPDFDoc,
                                       CFX_WordArray* nPageNum,
                                       CPDF_Document* pDestPDFDoc,
                                       int nIndex)
{
    int curpage = nIndex;

    nonstd::unique_ptr<ObjectNumberMap> pObjNumberMap(new ObjectNumberMap);

    for (int i = 0; i < nPageNum->GetSize(); ++i) {
        CPDF_Dictionary* pCurPageDict = pDestPDFDoc->CreateNewPage(curpage);
        CPDF_Dictionary* pSrcPageDict =
            pSrcPDFDoc->GetPage(nPageNum->GetAt(i) - 1);
        if (!pSrcPageDict || !pCurPageDict)
            return false;

        // Clone the page dictionary///////////
        FX_POSITION SrcPos = pSrcPageDict->GetStartPos();
        while (SrcPos) {
            CFX_ByteString cbSrcKeyStr;
            CPDF_Object* pObj = pSrcPageDict->GetNextElement(SrcPos,
                                                             cbSrcKeyStr);
            if (cbSrcKeyStr.Compare(("Type")) &&
                cbSrcKeyStr.Compare(("Parent"))) {
                if (pCurPageDict->KeyExist(cbSrcKeyStr))
                    pCurPageDict->RemoveAt(cbSrcKeyStr);
                pCurPageDict->SetAt(cbSrcKeyStr, pObj->Clone());
            }
        }

        //inheritable item///////////////////////
        CPDF_Object* pInheritable = nullptr;
        //1 MediaBox  //required
        if (!pCurPageDict->KeyExist("MediaBox")) {
            pInheritable = PageDictGetInheritableTag(pSrcPageDict, "MediaBox");
            if (!pInheritable) {
                // Search the "CropBox" from source page dictionary,
                // if not exists,we take the letter size.
                pInheritable = PageDictGetInheritableTag(pSrcPageDict,
                                                         "CropBox");
                if (pInheritable) {
                    pCurPageDict->SetAt("MediaBox", pInheritable->Clone());
                } else {
                    // Make the default size to be letter size (8.5'x11')
                    CPDF_Array* pArray = new CPDF_Array;
                    pArray->AddNumber(0);
                    pArray->AddNumber(0);
                    pArray->AddNumber(612);
                    pArray->AddNumber(792);
                    pCurPageDict->SetAt("MediaBox", pArray);
                }
            } else {
                pCurPageDict->SetAt("MediaBox", pInheritable->Clone());
            }
        }
        //2 Resources //required
        if (!pCurPageDict->KeyExist("Resources")) {
            pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Resources");
            if (!pInheritable)
                return false;
            pCurPageDict->SetAt("Resources", pInheritable->Clone());
        }
        //3 CropBox  //Optional
        if (!pCurPageDict->KeyExist("CropBox")) {
            pInheritable = PageDictGetInheritableTag(pSrcPageDict, "CropBox");
            if (pInheritable)
                pCurPageDict->SetAt("CropBox", pInheritable->Clone());
        }
        //4 Rotate  //Optional
        if (!pCurPageDict->KeyExist("Rotate")) {
            pInheritable = PageDictGetInheritableTag(pSrcPageDict, "Rotate");
            if (pInheritable)
                pCurPageDict->SetAt("Rotate", pInheritable->Clone());
        }

        /////////////////////////////////////////////
        //Update the reference
        FX_DWORD dwOldPageObj = pSrcPageDict->GetObjNum();
        FX_DWORD dwNewPageObj = pCurPageDict->GetObjNum();

        (*pObjNumberMap)[dwOldPageObj] = dwNewPageObj;

        UpdateReference(pCurPageDict, pDestPDFDoc, pObjNumberMap.get());
        ++curpage;
    }

    return true;
}

CPDF_Object* CPDF_PageOrganizer::PageDictGetInheritableTag(
    CPDF_Dictionary* pDict,
    CFX_ByteString nSrctag)
{
    if (!pDict || nSrctag.IsEmpty())
        return nullptr;
    if (!pDict->KeyExist("Parent") || !pDict->KeyExist("Type"))
        return nullptr;

    CPDF_Object* pType = pDict->GetElement("Type")->GetDirect();
    if (!pType || pType->GetType() != PDFOBJ_NAME)
        return nullptr;
    if (pType->GetString().Compare("Page"))
        return nullptr;

    CPDF_Object* pParent = pDict->GetElement("Parent")->GetDirect();
    if (!pParent || pParent->GetType() != PDFOBJ_DICTIONARY)
        return nullptr;

    if (pDict->KeyExist((const char*)nSrctag))
        return pDict->GetElement((const char*)nSrctag);

    CPDF_Dictionary* pp = (CPDF_Dictionary*)pParent;
    while (pp) {
        if (pp->KeyExist((const char*)nSrctag)) {
            return pp->GetElement((const char*)nSrctag);
        }
        if (!pp->KeyExist("Parent")) {
            break;
        }
        pp = (CPDF_Dictionary*)pp->GetElement("Parent")->GetDirect();
        if (pp->GetType() == PDFOBJ_NULL) {
            break;
        }
    }

    return nullptr;
}

bool CPDF_PageOrganizer::UpdateReference(CPDF_Object* pObj,
                                            CPDF_Document* pDoc,
                                            ObjectNumberMap* pObjNumberMap)
{
    switch (pObj->GetType()) {
        case PDFOBJ_REFERENCE: {
            CPDF_Reference* pReference = (CPDF_Reference*)pObj;
            FX_DWORD newobjnum = GetNewObjId(pDoc, pObjNumberMap, pReference);
            if (newobjnum == 0)
                return false;
            pReference->SetRef(pDoc, newobjnum);
            break;
        }
        case PDFOBJ_DICTIONARY: {
            CPDF_Dictionary* pDict = (CPDF_Dictionary*)pObj;

            FX_POSITION pos = pDict->GetStartPos();
            while (pos) {
                CFX_ByteString key("");
                CPDF_Object* pNextObj = pDict->GetNextElement(pos, key);
                if (!FXSYS_strcmp(key, "Parent") ||
                    !FXSYS_strcmp(key, "Prev") ||
                    !FXSYS_strcmp(key, "First")) {
                    continue;
                }
                if (pNextObj) {
                    if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
                      pDict->RemoveAt(key);
                } else {
                    return false;
                }
          }
          break;
        }
        case PDFOBJ_ARRAY: {
            CPDF_Array* pArray = (CPDF_Array*)pObj;
            FX_DWORD count = pArray->GetCount();
            for (FX_DWORD i = 0; i < count; ++i) {
                CPDF_Object* pNextObj = pArray->GetElement(i);
                if (!pNextObj)
                    return false;
                if (!UpdateReference(pNextObj, pDoc, pObjNumberMap))
                    return false;
            }
            break;
        }
        case PDFOBJ_STREAM: {
            CPDF_Stream* pStream = (CPDF_Stream*)pObj;
            CPDF_Dictionary* pDict = pStream->GetDict();
            if (pDict) {
                if (!UpdateReference(pDict, pDoc, pObjNumberMap))
                    return false;
            } else {
                return false;
            }
            break;
        }
        default:
            break;
    }

    return true;
}

FX_DWORD CPDF_PageOrganizer::GetNewObjId(CPDF_Document* pDoc,
                                         ObjectNumberMap* pObjNumberMap,
                                         CPDF_Reference* pRef)
{
    if (!pRef)
        return 0;

    FX_DWORD dwObjnum = pRef->GetRefObjNum();
    FX_DWORD dwNewObjNum = 0;
    const auto it = pObjNumberMap->find(dwObjnum);
    if (it != pObjNumberMap->end())
        dwNewObjNum = it->second;
    if (dwNewObjNum)
        return dwNewObjNum;

    CPDF_Object* pDirect = pRef->GetDirect();
    if (!pDirect)
        return 0;

    CPDF_Object* pClone = pDirect->Clone();
    if (!pClone)
        return 0;

    if (pClone->GetType() == PDFOBJ_DICTIONARY) {
        CPDF_Dictionary* pDictClone = (CPDF_Dictionary*)pClone;
        if (pDictClone->KeyExist("Type")) {
            CFX_ByteString strType = pDictClone->GetString("Type");
            if (!FXSYS_stricmp(strType, "Pages")) {
                pDictClone->Release();
                return 4;
            }
            if (!FXSYS_stricmp(strType, "Page")) {
                pDictClone->Release();
                return  0;
            }
        }
    }
    dwNewObjNum = pDoc->AddIndirectObject(pClone);
    (*pObjNumberMap)[dwObjnum] = dwNewObjNum;

    if (!UpdateReference(pClone, pDoc, pObjNumberMap)) {
        pClone->Release();
        return 0;
    }
    return dwNewObjNum;
}

FPDF_BOOL ParserPageRangeString(CFX_ByteString rangstring,
                                CFX_WordArray* pageArray,
                                int nCount)
{
    if (rangstring.GetLength() != 0) {
        rangstring.Remove(' ');
        int nLength = rangstring.GetLength();
        CFX_ByteString cbCompareString("0123456789-,");
        for (int i = 0; i < nLength; ++i) {
            if (cbCompareString.Find(rangstring[i]) == -1)
                return false;
        }
        CFX_ByteString cbMidRange;
        int nStringFrom = 0;
        int nStringTo = 0;
        while (nStringTo < nLength) {
            nStringTo = rangstring.Find(',', nStringFrom);
            if (nStringTo == -1)
                nStringTo = nLength;
            cbMidRange = rangstring.Mid(nStringFrom, nStringTo - nStringFrom);
            int nMid = cbMidRange.Find('-');
            if (nMid == -1) {
                long lPageNum = atol(cbMidRange);
                if (lPageNum <= 0 || lPageNum > nCount)
                    return false;
                pageArray->Add((FX_WORD)lPageNum);
            } else {
                int nStartPageNum = atol(cbMidRange.Mid(0, nMid));
                if (nStartPageNum == 0)
                    return false;

                ++nMid;
                int nEnd = cbMidRange.GetLength() - nMid;
                if (nEnd == 0)
                    return false;

                int nEndPageNum = atol(cbMidRange.Mid(nMid, nEnd));
                if (nStartPageNum < 0 ||
                    nStartPageNum >nEndPageNum ||
                    nEndPageNum > nCount) {
                    return false;
                }
                for (int i = nStartPageNum; i <= nEndPageNum; ++i) {
                    pageArray->Add(i);
                }
            }
            nStringFrom = nStringTo + 1;
        }
    }
    return true;
}

DLLEXPORT FPDF_BOOL STDCALL FPDF_ImportPages(FPDF_DOCUMENT dest_doc,
                                             FPDF_DOCUMENT src_doc,
                                             FPDF_BYTESTRING pagerange,
                                             int index)
{
    if (!dest_doc || !src_doc)
        return false;

    CFX_WordArray pageArray;
    CPDF_Document* pSrcDoc = (CPDF_Document*)src_doc;
    int nCount = pSrcDoc->GetPageCount();
    if (pagerange) {
        if (!ParserPageRangeString(pagerange,&pageArray,nCount))
            return false;
    } else {
        for (int i = 1; i <= nCount; ++i) {
            pageArray.Add(i);
        }
    }

    CPDF_Document* pDestDoc = (CPDF_Document*)dest_doc;
    CPDF_PageOrganizer pageOrg;

    pageOrg.PDFDocInit(pDestDoc, pSrcDoc);

    return pageOrg.ExportPage(pSrcDoc,&pageArray,pDestDoc,index);
}

DLLEXPORT FPDF_BOOL STDCALL FPDF_CopyViewerPreferences(FPDF_DOCUMENT dest_doc,
                                                       FPDF_DOCUMENT src_doc)
{
    if (!src_doc || !dest_doc)
        return false;

    CPDF_Document* pSrcDoc = (CPDF_Document*)src_doc;
    CPDF_Dictionary* pSrcDict = pSrcDoc->GetRoot();
    pSrcDict = pSrcDict->GetDict(FX_BSTRC("ViewerPreferences"));;
    if (!pSrcDict)
        return false;

    CPDF_Document* pDstDoc = (CPDF_Document*)dest_doc;
    CPDF_Dictionary* pDstDict = pDstDoc->GetRoot();
    if (!pDstDict)
        return false;
    pDstDict->SetAt(FX_BSTRC("ViewerPreferences"), pSrcDict->Clone(true));
    return true;
}
