// 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/include/xfa_checksum.h"

#include "core/fdrm/crypto/include/fx_crypt.h"
#include "xfa/fgas/crt/fgas_algorithm.h"

CXFA_SAXReaderHandler::CXFA_SAXReaderHandler(CXFA_ChecksumContext* pContext)
    : m_pContext(pContext) {
  FXSYS_assert(m_pContext);
}
CXFA_SAXReaderHandler::~CXFA_SAXReaderHandler() {}
void* CXFA_SAXReaderHandler::OnTagEnter(const CFX_ByteStringC& bsTagName,
                                        FX_SAXNODE eType,
                                        uint32_t dwStartPos) {
  UpdateChecksum(TRUE);
  if (eType != FX_SAXNODE_Tag && eType != FX_SAXNODE_Instruction) {
    return NULL;
  }
  m_SAXContext.m_eNode = eType;
  CFX_ByteTextBuf& textBuf = m_SAXContext.m_TextBuf;
  textBuf << "<";
  if (eType == FX_SAXNODE_Instruction) {
    textBuf << "?";
  }
  textBuf << bsTagName;
  m_SAXContext.m_bsTagName = bsTagName;
  return &m_SAXContext;
}
void CXFA_SAXReaderHandler::OnTagAttribute(void* pTag,
                                           const CFX_ByteStringC& bsAttri,
                                           const CFX_ByteStringC& bsValue) {
  if (pTag == NULL) {
    return;
  }
  CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
  textBuf << " " << bsAttri << "=\"" << bsValue << "\"";
}
void CXFA_SAXReaderHandler::OnTagBreak(void* pTag) {
  if (pTag == NULL) {
    return;
  }
  CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
  textBuf << ">";
  UpdateChecksum(FALSE);
}
void CXFA_SAXReaderHandler::OnTagData(void* pTag,
                                      FX_SAXNODE eType,
                                      const CFX_ByteStringC& bsData,
                                      uint32_t dwStartPos) {
  if (pTag == NULL) {
    return;
  }
  CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
  if (eType == FX_SAXNODE_CharData) {
    textBuf << "<![CDATA[";
  }
  textBuf << bsData;
  if (eType == FX_SAXNODE_CharData) {
    textBuf << "]]>";
  }
}
void CXFA_SAXReaderHandler::OnTagClose(void* pTag, uint32_t dwEndPos) {
  if (pTag == NULL) {
    return;
  }
  CXFA_SAXContext* pSAXContext = (CXFA_SAXContext*)pTag;
  CFX_ByteTextBuf& textBuf = pSAXContext->m_TextBuf;
  if (pSAXContext->m_eNode == FX_SAXNODE_Instruction) {
    textBuf << "?>";
  } else if (pSAXContext->m_eNode == FX_SAXNODE_Tag) {
    textBuf << "></" << pSAXContext->m_bsTagName.AsStringC() << ">";
  }
  UpdateChecksum(FALSE);
}
void CXFA_SAXReaderHandler::OnTagEnd(void* pTag,
                                     const CFX_ByteStringC& bsTagName,
                                     uint32_t dwEndPos) {
  if (pTag == NULL) {
    return;
  }
  CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
  textBuf << "</" << bsTagName << ">";
  UpdateChecksum(FALSE);
}
void CXFA_SAXReaderHandler::OnTargetData(void* pTag,
                                         FX_SAXNODE eType,
                                         const CFX_ByteStringC& bsData,
                                         uint32_t dwStartPos) {
  if (pTag == NULL && eType != FX_SAXNODE_Comment) {
    return;
  }
  if (eType == FX_SAXNODE_Comment) {
    CFX_ByteTextBuf& textBuf = m_SAXContext.m_TextBuf;
    textBuf << "<!--" << bsData << "-->";
    UpdateChecksum(FALSE);
  } else {
    CFX_ByteTextBuf& textBuf = ((CXFA_SAXContext*)pTag)->m_TextBuf;
    textBuf << " " << bsData;
  }
}
void CXFA_SAXReaderHandler::UpdateChecksum(FX_BOOL bCheckSpace) {
  int32_t iLength = m_SAXContext.m_TextBuf.GetLength();
  if (iLength < 1) {
    return;
  }
  uint8_t* pBuffer = m_SAXContext.m_TextBuf.GetBuffer();
  FX_BOOL bUpdata = TRUE;
  if (bCheckSpace) {
    bUpdata = FALSE;
    for (int32_t i = 0; i < iLength; i++) {
      bUpdata = (pBuffer[i] > 0x20);
      if (bUpdata) {
        break;
      }
    }
  }
  if (bUpdata) {
    m_pContext->Update(CFX_ByteStringC(pBuffer, iLength));
  }
  m_SAXContext.m_TextBuf.Clear();
}

CXFA_ChecksumContext::CXFA_ChecksumContext()
    : m_pSAXReader(NULL), m_pByteContext(NULL) {}
CXFA_ChecksumContext::~CXFA_ChecksumContext() {
  FinishChecksum();
}
FX_BOOL CXFA_ChecksumContext::StartChecksum() {
  FinishChecksum();
  m_pByteContext = FX_Alloc(uint8_t, 128);
  CRYPT_SHA1Start(m_pByteContext);
  m_bsChecksum.clear();
  m_pSAXReader = FX_SAXReader_Create();
  return m_pSAXReader != NULL;
}
FX_BOOL CXFA_ChecksumContext::UpdateChecksum(IFX_FileRead* pSrcFile,
                                             FX_FILESIZE offset,
                                             size_t size) {
  if (m_pSAXReader == NULL) {
    return FALSE;
  }
  if (pSrcFile == NULL) {
    return FALSE;
  }
  if (size < 1) {
    size = pSrcFile->GetSize();
  }
  CXFA_SAXReaderHandler handler(this);
  m_pSAXReader->SetHandler(&handler);
  if (m_pSAXReader->StartParse(
          pSrcFile, (uint32_t)offset, (uint32_t)size,
          FX_SAXPARSEMODE_NotSkipSpace | FX_SAXPARSEMODE_NotConvert_amp |
              FX_SAXPARSEMODE_NotConvert_lt | FX_SAXPARSEMODE_NotConvert_gt |
              FX_SAXPARSEMODE_NotConvert_sharp) < 0) {
    return FALSE;
  }
  return m_pSAXReader->ContinueParse(NULL) > 99;
}
void CXFA_ChecksumContext::FinishChecksum() {
  if (m_pSAXReader) {
    m_pSAXReader->Release();
    m_pSAXReader = NULL;
  }
  if (m_pByteContext) {
    uint8_t digest[20];
    FXSYS_memset(digest, 0, 20);
    CRYPT_SHA1Finish(m_pByteContext, digest);
    int32_t nLen = FX_Base64EncodeA(digest, 20, NULL);
    FX_CHAR* pBuffer = m_bsChecksum.GetBuffer(nLen);
    FX_Base64EncodeA(digest, 20, pBuffer);
    m_bsChecksum.ReleaseBuffer(nLen);
    FX_Free(m_pByteContext);
    m_pByteContext = NULL;
  }
}
void CXFA_ChecksumContext::GetChecksum(CFX_ByteString& bsChecksum) {
  bsChecksum = m_bsChecksum;
}
void CXFA_ChecksumContext::Update(const CFX_ByteStringC& bsText) {
  if (m_pByteContext) {
    CRYPT_SHA1Update(m_pByteContext, bsText.raw_str(), bsText.GetLength());
  }
}
