// 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/fpdfapi/fpdf_serial.h"
CFDF_Document::CFDF_Document() : CPDF_IndirectObjects(NULL) {
  m_pRootDict = NULL;
  m_pFile = NULL;
  m_bOwnFile = FALSE;
}
CFDF_Document::~CFDF_Document() {
  if (m_bOwnFile && m_pFile) {
    m_pFile->Release();
  }
}
CFDF_Document* CFDF_Document::CreateNewDoc() {
  CFDF_Document* pDoc = new CFDF_Document;
  pDoc->m_pRootDict = new CPDF_Dictionary;
  pDoc->AddIndirectObject(pDoc->m_pRootDict);
  CPDF_Dictionary* pFDFDict = new CPDF_Dictionary;
  pDoc->m_pRootDict->SetAt(FX_BSTRC("FDF"), pFDFDict);
  return pDoc;
}
CFDF_Document* CFDF_Document::ParseFile(IFX_FileRead* pFile, FX_BOOL bOwnFile) {
  if (!pFile) {
    return NULL;
  }
  CFDF_Document* pDoc = new CFDF_Document;
  pDoc->ParseStream(pFile, bOwnFile);
  if (pDoc->m_pRootDict == NULL) {
    delete pDoc;
    return NULL;
  }
  return pDoc;
}
CFDF_Document* CFDF_Document::ParseMemory(const uint8_t* pData, FX_DWORD size) {
  return CFDF_Document::ParseFile(FX_CreateMemoryStream((uint8_t*)pData, size),
                                  TRUE);
}
void CFDF_Document::ParseStream(IFX_FileRead* pFile, FX_BOOL bOwnFile) {
  m_pFile = pFile;
  m_bOwnFile = bOwnFile;
  CPDF_SyntaxParser parser;
  parser.InitParser(m_pFile, 0);
  while (1) {
    FX_BOOL bNumber;
    CFX_ByteString word = parser.GetNextWord(bNumber);
    if (bNumber) {
      FX_DWORD objnum = FXSYS_atoi(word);
      word = parser.GetNextWord(bNumber);
      if (!bNumber) {
        break;
      }
      word = parser.GetNextWord(bNumber);
      if (word != FX_BSTRC("obj")) {
        break;
      }
      CPDF_Object* pObj = parser.GetObject(this, objnum, 0, 0);
      if (pObj == NULL) {
        break;
      }
      InsertIndirectObject(objnum, pObj);
      word = parser.GetNextWord(bNumber);
      if (word != FX_BSTRC("endobj")) {
        break;
      }
    } else {
      if (word != FX_BSTRC("trailer")) {
        break;
      }
      CPDF_Dictionary* pMainDict =
          (CPDF_Dictionary*)parser.GetObject(this, 0, 0, 0);
      if (pMainDict == NULL || pMainDict->GetType() != PDFOBJ_DICTIONARY) {
        break;
      }
      m_pRootDict = pMainDict->GetDict(FX_BSTRC("Root"));
      pMainDict->Release();
      break;
    }
  }
}
FX_BOOL CFDF_Document::WriteBuf(CFX_ByteTextBuf& buf) const {
  if (m_pRootDict == NULL) {
    return FALSE;
  }
  buf << FX_BSTRC("%FDF-1.2\r\n");
  FX_POSITION pos = m_IndirectObjs.GetStartPosition();
  while (pos) {
    size_t objnum;
    CPDF_Object* pObj;
    m_IndirectObjs.GetNextAssoc(pos, (void*&)objnum, (void*&)pObj);
    buf << (FX_DWORD)objnum << FX_BSTRC(" 0 obj\r\n") << pObj
        << FX_BSTRC("\r\nendobj\r\n\r\n");
  }
  buf << FX_BSTRC("trailer\r\n<</Root ") << m_pRootDict->GetObjNum()
      << FX_BSTRC(" 0 R>>\r\n%%EOF\r\n");
  return TRUE;
}
CFX_WideString CFDF_Document::GetWin32Path() const {
  CPDF_Dictionary* pDict =
      m_pRootDict ? m_pRootDict->GetDict(FX_BSTRC("FDF")) : NULL;
  CPDF_Object* pFileSpec = pDict ? pDict->GetElementValue(FX_BSTRC("F")) : NULL;
  if (pFileSpec == NULL) {
    return CFX_WideString();
  }
  if (pFileSpec->GetType() == PDFOBJ_STRING) {
    return FPDF_FileSpec_GetWin32Path(m_pRootDict->GetDict(FX_BSTRC("FDF")));
  }
  return FPDF_FileSpec_GetWin32Path(pFileSpec);
}
static CFX_WideString ChangeSlash(const FX_WCHAR* str) {
  CFX_WideString result;
  while (*str) {
    if (*str == '\\') {
      result += '/';
    } else if (*str == '/') {
      result += '\\';
    } else {
      result += *str;
    }
    str++;
  }
  return result;
}
void FPDF_FileSpec_SetWin32Path(CPDF_Object* pFileSpec,
                                const CFX_WideString& filepath) {
  CFX_WideString result;
  if (filepath.GetLength() > 1 && filepath[1] == ':') {
    result = L"/";
    result += filepath[0];
    if (filepath[2] != '\\') {
      result += '/';
    }
    result += ChangeSlash(filepath.c_str() + 2);
  } else if (filepath.GetLength() > 1 && filepath[0] == '\\' &&
             filepath[1] == '\\') {
    result = ChangeSlash(filepath.c_str() + 1);
  } else {
    result = ChangeSlash(filepath.c_str());
  }
  if (pFileSpec->GetType() == PDFOBJ_STRING) {
    pFileSpec->SetString(CFX_ByteString::FromUnicode(result));
  } else if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) {
    ((CPDF_Dictionary*)pFileSpec)
        ->SetAtString(FX_BSTRC("F"), CFX_ByteString::FromUnicode(result));
    ((CPDF_Dictionary*)pFileSpec)
        ->SetAtString(FX_BSTRC("UF"), PDF_EncodeText(result));
    ((CPDF_Dictionary*)pFileSpec)->RemoveAt(FX_BSTRC("FS"));
  }
}
CFX_WideString FPDF_FileSpec_GetWin32Path(const CPDF_Object* pFileSpec) {
  CFX_WideString wsFileName;
  if (pFileSpec->GetType() == PDFOBJ_DICTIONARY) {
    CPDF_Dictionary* pDict = (CPDF_Dictionary*)pFileSpec;
    wsFileName = pDict->GetUnicodeText(FX_BSTRC("UF"));
    if (wsFileName.IsEmpty()) {
      wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("F")));
    }
    if (pDict->GetString(FX_BSTRC("FS")) == FX_BSTRC("URL")) {
      return wsFileName;
    }
    if (wsFileName.IsEmpty() && pDict->KeyExist(FX_BSTRC("DOS"))) {
      wsFileName = CFX_WideString::FromLocal(pDict->GetString(FX_BSTRC("DOS")));
    }
  } else if (!pFileSpec)
    wsFileName = CFX_WideString();
  else {
    wsFileName = CFX_WideString::FromLocal(pFileSpec->GetString());
  }
  if (wsFileName[0] != '/') {
    return ChangeSlash(wsFileName.c_str());
  }
  if (wsFileName[2] == '/') {
    CFX_WideString result;
    result += wsFileName[1];
    result += ':';
    result += ChangeSlash(wsFileName.c_str() + 2);
    return result;
  }
  CFX_WideString result;
  result += '\\';
  result += ChangeSlash(wsFileName.c_str());
  return result;
}
