// 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 "xfa/fxfa/cxfa_ffdoc.h"

#include <algorithm>
#include <memory>
#include <vector>

#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_document.h"
#include "core/fpdfapi/parser/fpdf_parser_decode.h"
#include "core/fpdfdoc/cpdf_nametree.h"
#include "core/fxcrt/cfx_checksumcontext.h"
#include "core/fxcrt/cfx_memorystream.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_memory.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "third_party/base/ptr_util.h"
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fxfa/app/cxfa_ffnotify.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdocview.h"
#include "xfa/fxfa/cxfa_ffwidget.h"
#include "xfa/fxfa/cxfa_fileread.h"
#include "xfa/fxfa/cxfa_fontmgr.h"
#include "xfa/fxfa/parser/cxfa_dataexporter.h"
#include "xfa/fxfa/parser/cxfa_dataimporter.h"
#include "xfa/fxfa/parser/cxfa_document.h"
#include "xfa/fxfa/parser/cxfa_node.h"

namespace {

struct FX_BASE64DATA {
  uint32_t data1 : 2;
  uint32_t data2 : 6;
  uint32_t data3 : 4;
  uint32_t data4 : 4;
  uint32_t data5 : 6;
  uint32_t data6 : 2;
  uint32_t data7 : 8;
};

const uint8_t kStartValuesRemoved = 43;
const uint8_t kDecoderMapSize = 80;
const uint8_t g_FXBase64DecoderMap[kDecoderMapSize] = {
    0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A,
    0x3B, 0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
    0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
    0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
    0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
    0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B,
    0x2C, 0x2D, 0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33,
};

uint8_t base64DecoderValue(uint8_t val) {
  if (val < kStartValuesRemoved || val >= kStartValuesRemoved + kDecoderMapSize)
    return 0xFF;
  return g_FXBase64DecoderMap[val - kStartValuesRemoved];
}

void Base64DecodePiece(const char src[4],
                       int32_t iChars,
                       FX_BASE64DATA& dst,
                       int32_t& iBytes) {
  ASSERT(iChars > 0 && iChars < 5);
  iBytes = 1;
  dst.data2 = base64DecoderValue(static_cast<uint8_t>(src[0]));
  if (iChars > 1) {
    uint8_t b = base64DecoderValue(static_cast<uint8_t>(src[1]));
    dst.data1 = b >> 4;
    dst.data4 = b;
    if (iChars > 2) {
      iBytes = 2;
      b = base64DecoderValue(static_cast<uint8_t>(src[2]));
      dst.data3 = b >> 2;
      dst.data6 = b;
      if (iChars > 3) {
        iBytes = 3;
        dst.data5 = base64DecoderValue(static_cast<uint8_t>(src[3]));
      } else {
        dst.data5 = 0;
      }
    } else {
      dst.data3 = 0;
    }
  } else {
    dst.data1 = 0;
  }
}

int32_t Base64DecodeW(const wchar_t* pSrc, int32_t iSrcLen, uint8_t* pDst) {
  ASSERT(pSrc);
  if (iSrcLen < 1) {
    return 0;
  }
  while (iSrcLen > 0 && pSrc[iSrcLen - 1] == '=') {
    iSrcLen--;
  }
  if (iSrcLen < 1) {
    return 0;
  }
  if (!pDst) {
    int32_t iDstLen = iSrcLen / 4 * 3;
    iSrcLen %= 4;
    if (iSrcLen == 1) {
      iDstLen += 1;
    } else if (iSrcLen == 2) {
      iDstLen += 1;
    } else if (iSrcLen == 3) {
      iDstLen += 2;
    }
    return iDstLen;
  }
  char srcData[4];
  FX_BASE64DATA dstData;
  int32_t iChars = 4, iBytes;
  uint8_t* pDstEnd = pDst;
  while (iSrcLen > 0) {
    if (iSrcLen > 3) {
      srcData[0] = (char)*pSrc++;
      srcData[1] = (char)*pSrc++;
      srcData[2] = (char)*pSrc++;
      srcData[3] = (char)*pSrc++;
      iSrcLen -= 4;
    } else {
      *((uint32_t*)&dstData) = 0;
      *((uint32_t*)srcData) = 0;
      srcData[0] = (char)*pSrc++;
      if (iSrcLen > 1) {
        srcData[1] = (char)*pSrc++;
      }
      if (iSrcLen > 2) {
        srcData[2] = (char)*pSrc++;
      }
      iChars = iSrcLen;
      iSrcLen = 0;
    }
    Base64DecodePiece(srcData, iChars, dstData, iBytes);
    *pDstEnd++ = ((uint8_t*)&dstData)[0];
    if (iBytes > 1) {
      *pDstEnd++ = ((uint8_t*)&dstData)[1];
    }
    if (iBytes > 2) {
      *pDstEnd++ = ((uint8_t*)&dstData)[2];
    }
  }
  return pDstEnd - pDst;
}

}  // namespace

CXFA_FFDoc::CXFA_FFDoc(CXFA_FFApp* pApp, IXFA_DocEnvironment* pDocEnvironment)
    : m_pDocEnvironment(pDocEnvironment),
      m_pDocumentParser(nullptr),
      m_pApp(pApp),
      m_pNotify(nullptr),
      m_pPDFDoc(nullptr),
      m_dwDocType(XFA_DocType::Static) {}

CXFA_FFDoc::~CXFA_FFDoc() {
  CloseDoc();
}

int32_t CXFA_FFDoc::StartLoad() {
  m_pNotify = pdfium::MakeUnique<CXFA_FFNotify>(this);
  m_pDocumentParser = pdfium::MakeUnique<CXFA_DocumentParser>(m_pNotify.get());
  return m_pDocumentParser->StartParse(m_pStream, XFA_XDPPACKET_XDP);
}

bool XFA_GetPDFContentsFromPDFXML(CFX_XMLNode* pPDFElement,
                                  uint8_t*& pByteBuffer,
                                  int32_t& iBufferSize) {
  CFX_XMLElement* pDocumentElement = nullptr;
  for (CFX_XMLNode* pXMLNode =
           pPDFElement->GetNodeItem(CFX_XMLNode::FirstChild);
       pXMLNode; pXMLNode = pXMLNode->GetNodeItem(CFX_XMLNode::NextSibling)) {
    if (pXMLNode->GetType() == FX_XMLNODE_Element) {
      CFX_XMLElement* pXMLElement = static_cast<CFX_XMLElement*>(pXMLNode);
      CFX_WideString wsTagName = pXMLElement->GetName();
      if (wsTagName == L"document") {
        pDocumentElement = pXMLElement;
        break;
      }
    }
  }
  if (!pDocumentElement) {
    return false;
  }
  CFX_XMLElement* pChunkElement = nullptr;
  for (CFX_XMLNode* pXMLNode =
           pDocumentElement->GetNodeItem(CFX_XMLNode::FirstChild);
       pXMLNode; pXMLNode = pXMLNode->GetNodeItem(CFX_XMLNode::NextSibling)) {
    if (pXMLNode->GetType() == FX_XMLNODE_Element) {
      CFX_XMLElement* pXMLElement = static_cast<CFX_XMLElement*>(pXMLNode);
      CFX_WideString wsTagName = pXMLElement->GetName();
      if (wsTagName == L"chunk") {
        pChunkElement = pXMLElement;
        break;
      }
    }
  }
  if (!pChunkElement) {
    return false;
  }
  CFX_WideString wsPDFContent = pChunkElement->GetTextData();
  iBufferSize =
      Base64DecodeW(wsPDFContent.c_str(), wsPDFContent.GetLength(), nullptr);
  pByteBuffer = FX_Alloc(uint8_t, iBufferSize + 1);
  pByteBuffer[iBufferSize] = '0';  // FIXME: I bet this is wrong.
  Base64DecodeW(wsPDFContent.c_str(), wsPDFContent.GetLength(), pByteBuffer);
  return true;
}
void XFA_XPDPacket_MergeRootNode(CXFA_Node* pOriginRoot, CXFA_Node* pNewRoot) {
  CXFA_Node* pChildNode = pNewRoot->GetNodeItem(XFA_NODEITEM_FirstChild);
  while (pChildNode) {
    CXFA_Node* pOriginChild =
        pOriginRoot->GetFirstChildByName(pChildNode->GetNameHash());
    if (pOriginChild) {
      pChildNode = pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
    } else {
      CXFA_Node* pNextSibling =
          pChildNode->GetNodeItem(XFA_NODEITEM_NextSibling);
      pNewRoot->RemoveChild(pChildNode);
      pOriginRoot->InsertChild(pChildNode);
      pChildNode = pNextSibling;
      pNextSibling = nullptr;
    }
  }
}

int32_t CXFA_FFDoc::DoLoad() {
  int32_t iStatus = m_pDocumentParser->DoParse();
  if (iStatus == XFA_PARSESTATUS_Done && !m_pPDFDoc)
    return XFA_PARSESTATUS_SyntaxErr;
  return iStatus;
}

void CXFA_FFDoc::StopLoad() {
  m_pApp->GetXFAFontMgr()->LoadDocFonts(this);
  m_dwDocType = XFA_DocType::Static;
  CXFA_Node* pConfig = ToNode(
      m_pDocumentParser->GetDocument()->GetXFAObject(XFA_HASHCODE_Config));
  if (!pConfig)
    return;

  CXFA_Node* pAcrobat = pConfig->GetFirstChildByClass(XFA_Element::Acrobat);
  if (!pAcrobat)
    return;

  CXFA_Node* pAcrobat7 = pAcrobat->GetFirstChildByClass(XFA_Element::Acrobat7);
  if (!pAcrobat7)
    return;

  CXFA_Node* pDynamicRender =
      pAcrobat7->GetFirstChildByClass(XFA_Element::DynamicRender);
  if (!pDynamicRender)
    return;

  CFX_WideString wsType;
  if (pDynamicRender->TryContent(wsType) && wsType == L"required")
    m_dwDocType = XFA_DocType::Dynamic;
}

CXFA_FFDocView* CXFA_FFDoc::CreateDocView() {
  if (!m_DocView)
    m_DocView = pdfium::MakeUnique<CXFA_FFDocView>(this);

  return m_DocView.get();
}

CXFA_FFDocView* CXFA_FFDoc::GetDocView(CXFA_LayoutProcessor* pLayout) {
  return m_DocView && m_DocView->GetXFALayout() == pLayout ? m_DocView.get()
                                                           : nullptr;
}

CXFA_FFDocView* CXFA_FFDoc::GetDocView() {
  return m_DocView.get();
}

bool CXFA_FFDoc::OpenDoc(const CFX_RetainPtr<IFX_SeekableStream>& pStream) {
  m_pStream = pStream;
  return true;
}

bool CXFA_FFDoc::OpenDoc(CPDF_Document* pPDFDoc) {
  if (!pPDFDoc)
    return false;

  CPDF_Dictionary* pRoot = pPDFDoc->GetRoot();
  if (!pRoot)
    return false;

  CPDF_Dictionary* pAcroForm = pRoot->GetDictFor("AcroForm");
  if (!pAcroForm)
    return false;

  CPDF_Object* pElementXFA = pAcroForm->GetDirectObjectFor("XFA");
  if (!pElementXFA)
    return false;

  std::vector<CPDF_Stream*> xfaStreams;
  if (pElementXFA->IsArray()) {
    CPDF_Array* pXFAArray = (CPDF_Array*)pElementXFA;
    for (size_t i = 0; i < pXFAArray->GetCount() / 2; i++) {
      if (CPDF_Stream* pStream = pXFAArray->GetStreamAt(i * 2 + 1))
        xfaStreams.push_back(pStream);
    }
  } else if (pElementXFA->IsStream()) {
    xfaStreams.push_back((CPDF_Stream*)pElementXFA);
  }
  if (xfaStreams.empty())
    return false;

  m_pPDFDoc = pPDFDoc;
  m_pStream = pdfium::MakeRetain<CXFA_FileRead>(xfaStreams);
  return true;
}

void CXFA_FFDoc::CloseDoc() {
  if (m_DocView) {
    m_DocView->RunDocClose();
    m_DocView.reset();
  }
  CXFA_Document* doc =
      m_pDocumentParser ? m_pDocumentParser->GetDocument() : nullptr;
  if (doc)
    doc->ClearLayoutData();

  m_pNotify.reset();
  m_pApp->GetXFAFontMgr()->ReleaseDocFonts(this);
  m_HashToDibDpiMap.clear();
  m_pApp->ClearEventTargets();
}

CFX_RetainPtr<CFX_DIBitmap> CXFA_FFDoc::GetPDFNamedImage(
    const CFX_WideStringC& wsName,
    int32_t& iImageXDpi,
    int32_t& iImageYDpi) {
  if (!m_pPDFDoc)
    return nullptr;

  uint32_t dwHash = FX_HashCode_GetW(wsName, false);
  auto it = m_HashToDibDpiMap.find(dwHash);
  if (it != m_HashToDibDpiMap.end()) {
    iImageXDpi = it->second.iImageXDpi;
    iImageYDpi = it->second.iImageYDpi;
    return it->second.pDibSource.As<CFX_DIBitmap>();
  }

  CPDF_Dictionary* pRoot = m_pPDFDoc->GetRoot();
  if (!pRoot)
    return nullptr;

  CPDF_Dictionary* pNames = pRoot->GetDictFor("Names");
  if (!pNames)
    return nullptr;

  CPDF_Dictionary* pXFAImages = pNames->GetDictFor("XFAImages");
  if (!pXFAImages)
    return nullptr;

  CPDF_NameTree nametree(pXFAImages);
  CFX_ByteString bsName = PDF_EncodeText(wsName.c_str(), wsName.GetLength());
  CPDF_Object* pObject = nametree.LookupValue(bsName);
  if (!pObject) {
    for (size_t i = 0; i < nametree.GetCount(); i++) {
      CFX_ByteString bsTemp;
      CPDF_Object* pTempObject = nametree.LookupValueAndName(i, &bsTemp);
      if (bsTemp == bsName) {
        pObject = pTempObject;
        break;
      }
    }
  }

  CPDF_Stream* pStream = ToStream(pObject);
  if (!pStream)
    return nullptr;

  auto pAcc = pdfium::MakeRetain<CPDF_StreamAcc>(pStream);
  pAcc->LoadAllData();

  CFX_RetainPtr<IFX_SeekableStream> pImageFileRead =
      pdfium::MakeRetain<CFX_MemoryStream>(
          const_cast<uint8_t*>(pAcc->GetData()), pAcc->GetSize(), false);

  CFX_RetainPtr<CFX_DIBitmap> pDibSource = XFA_LoadImageFromBuffer(
      pImageFileRead, FXCODEC_IMAGE_UNKNOWN, iImageXDpi, iImageYDpi);
  m_HashToDibDpiMap[dwHash] = {pDibSource, iImageXDpi, iImageYDpi};
  return pDibSource;
}

bool CXFA_FFDoc::SavePackage(XFA_HashCode code,
                             const CFX_RetainPtr<IFX_SeekableStream>& pFile,
                             CFX_ChecksumContext* pCSContext) {
  CXFA_Document* doc = m_pDocumentParser->GetDocument();
  auto pExport = pdfium::MakeUnique<CXFA_DataExporter>(doc);
  CXFA_Node* pNode = code == XFA_HASHCODE_Xfa ? doc->GetRoot()
                                              : ToNode(doc->GetXFAObject(code));
  if (!pNode)
    return !!pExport->Export(pFile);

  CFX_ByteString bsChecksum;
  if (pCSContext)
    bsChecksum = pCSContext->GetChecksum();

  return !!pExport->Export(
      pFile, pNode, 0, bsChecksum.GetLength() ? bsChecksum.c_str() : nullptr);
}

bool CXFA_FFDoc::ImportData(const CFX_RetainPtr<IFX_SeekableStream>& pStream,
                            bool bXDP) {
  auto importer =
      pdfium::MakeUnique<CXFA_DataImporter>(m_pDocumentParser->GetDocument());
  return importer->ImportData(pStream);
}
