// Copyright 2016 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 "core/fpdfapi/page/cpdf_contentparser.h"

#include <utility>

#include "constants/page_object.h"
#include "core/fpdfapi/font/cpdf_type3char.h"
#include "core/fpdfapi/page/cpdf_allstates.h"
#include "core/fpdfapi/page/cpdf_form.h"
#include "core/fpdfapi/page/cpdf_page.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
#include "core/fpdfapi/page/cpdf_path.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/cpdf_stream.h"
#include "core/fpdfapi/parser/cpdf_stream_acc.h"
#include "core/fxcrt/fx_safe_types.h"
#include "core/fxcrt/pauseindicator_iface.h"
#include "core/fxcrt/span_util.h"
#include "core/fxcrt/stl_util.h"
#include "core/fxge/cfx_fillrenderoptions.h"
#include "third_party/base/check.h"
#include "third_party/base/check_op.h"

CPDF_ContentParser::OwnedData::OwnedData(
    std::unique_ptr<uint8_t, FxFreeDeleter> buffer,
    uint32_t size)
    : buffer(std::move(buffer)), size(size) {}

CPDF_ContentParser::OwnedData::~OwnedData() = default;

CPDF_ContentParser::CPDF_ContentParser(CPDF_Page* pPage)
    : m_CurrentStage(Stage::kGetContent), m_pObjectHolder(pPage) {
  DCHECK(pPage);
  if (!pPage->GetDocument()) {
    m_CurrentStage = Stage::kComplete;
    return;
  }

  RetainPtr<CPDF_Object> pContent =
      pPage->GetMutableDict()->GetMutableDirectObjectFor(
          pdfium::page_object::kContents);
  if (!pContent) {
    HandlePageContentFailure();
    return;
  }

  const CPDF_Stream* pStream = pContent->AsStream();
  if (pStream) {
    HandlePageContentStream(pStream);
    return;
  }

  const CPDF_Array* pArray = pContent->AsArray();
  if (pArray && HandlePageContentArray(pArray))
    return;

  HandlePageContentFailure();
}

CPDF_ContentParser::CPDF_ContentParser(CPDF_Form* pForm,
                                       const CPDF_AllStates* pGraphicStates,
                                       const CFX_Matrix* pParentMatrix,
                                       CPDF_Type3Char* pType3Char,
                                       std::set<const uint8_t*>* pParsedSet)
    : m_CurrentStage(Stage::kParse),
      m_pObjectHolder(pForm),
      m_pType3Char(pType3Char) {
  DCHECK(pForm);
  CFX_Matrix form_matrix = pForm->GetDict()->GetMatrixFor("Matrix");
  if (pGraphicStates)
    form_matrix.Concat(pGraphicStates->m_CTM);

  RetainPtr<const CPDF_Array> pBBox = pForm->GetDict()->GetArrayFor("BBox");
  CFX_FloatRect form_bbox;
  CPDF_Path ClipPath;
  if (pBBox) {
    form_bbox = pBBox->GetRect();
    ClipPath.Emplace();
    ClipPath.AppendFloatRect(form_bbox);
    ClipPath.Transform(form_matrix);
    if (pParentMatrix)
      ClipPath.Transform(*pParentMatrix);

    form_bbox = form_matrix.TransformRect(form_bbox);
    if (pParentMatrix)
      form_bbox = pParentMatrix->TransformRect(form_bbox);
  }

  RetainPtr<CPDF_Dictionary> pResources =
      pForm->GetMutableDict()->GetMutableDictFor("Resources");
  m_pParser = std::make_unique<CPDF_StreamContentParser>(
      pForm->GetDocument(), pForm->GetMutablePageResources(),
      pForm->GetMutableResources(), pParentMatrix, pForm, std::move(pResources),
      form_bbox, pGraphicStates, pParsedSet);
  m_pParser->GetCurStates()->m_CTM = form_matrix;
  m_pParser->GetCurStates()->m_ParentMatrix = form_matrix;
  if (ClipPath.HasRef()) {
    m_pParser->GetCurStates()->m_ClipPath.AppendPathWithAutoMerge(
        ClipPath, CFX_FillRenderOptions::FillType::kWinding);
  }
  if (pForm->GetTransparency().IsGroup()) {
    CPDF_GeneralState* pState = &m_pParser->GetCurStates()->m_GeneralState;
    pState->SetBlendType(BlendMode::kNormal);
    pState->SetStrokeAlpha(1.0f);
    pState->SetFillAlpha(1.0f);
    pState->SetSoftMask(nullptr);
  }
  m_pSingleStream = pdfium::MakeRetain<CPDF_StreamAcc>(
      pdfium::WrapRetain(pForm->GetStream()));
  m_pSingleStream->LoadAllDataFiltered();
  m_Data = m_pSingleStream->GetSpan();
}

CPDF_ContentParser::~CPDF_ContentParser() = default;

// Returning |true| means that there is more content to be processed and
// Continue() should be called again. Returning |false| means that we've
// completed the parse and Continue() is complete.
bool CPDF_ContentParser::Continue(PauseIndicatorIface* pPause) {
  while (m_CurrentStage == Stage::kGetContent) {
    m_CurrentStage = GetContent();
    if (pPause && pPause->NeedToPauseNow())
      return true;
  }

  if (m_CurrentStage == Stage::kPrepareContent)
    m_CurrentStage = PrepareContent();

  while (m_CurrentStage == Stage::kParse) {
    m_CurrentStage = Parse();
    if (pPause && pPause->NeedToPauseNow())
      return true;
  }

  if (m_CurrentStage == Stage::kCheckClip)
    m_CurrentStage = CheckClip();

  DCHECK_EQ(m_CurrentStage, Stage::kComplete);
  return false;
}

CPDF_ContentParser::Stage CPDF_ContentParser::GetContent() {
  DCHECK_EQ(m_CurrentStage, Stage::kGetContent);
  DCHECK(m_pObjectHolder->IsPage());
  RetainPtr<const CPDF_Array> pContent =
      m_pObjectHolder->GetDict()->GetArrayFor(pdfium::page_object::kContents);
  RetainPtr<const CPDF_Stream> pStreamObj = ToStream(
      pContent ? pContent->GetDirectObjectAt(m_CurrentOffset) : nullptr);
  m_StreamArray[m_CurrentOffset] =
      pdfium::MakeRetain<CPDF_StreamAcc>(std::move(pStreamObj));
  m_StreamArray[m_CurrentOffset]->LoadAllDataFiltered();
  m_CurrentOffset++;

  return m_CurrentOffset == m_nStreams ? Stage::kPrepareContent
                                       : Stage::kGetContent;
}

CPDF_ContentParser::Stage CPDF_ContentParser::PrepareContent() {
  m_CurrentOffset = 0;

  if (m_StreamArray.empty()) {
    m_Data = m_pSingleStream->GetSpan();
    return Stage::kParse;
  }

  FX_SAFE_UINT32 safe_size = 0;
  for (const auto& stream : m_StreamArray) {
    m_StreamSegmentOffsets.push_back(safe_size.ValueOrDie());
    safe_size += stream->GetSize();
    safe_size += 1;
    if (!safe_size.IsValid())
      return Stage::kComplete;
  }

  const size_t buffer_size = safe_size.ValueOrDie();
  std::unique_ptr<uint8_t, FxFreeDeleter> buffer(
      FX_TryAlloc(uint8_t, buffer_size));
  if (!buffer) {
    m_Data.emplace<pdfium::span<const uint8_t>>();
    return Stage::kComplete;
  }

  size_t pos = 0;
  auto data_span = pdfium::make_span(buffer.get(), buffer_size);
  for (const auto& stream : m_StreamArray) {
    fxcrt::spancpy(data_span.subspan(pos), stream->GetSpan());
    pos += stream->GetSize();
    data_span[pos++] = ' ';
  }
  m_StreamArray.clear();
  m_Data.emplace<OwnedData>(std::move(buffer), buffer_size);
  return Stage::kParse;
}

CPDF_ContentParser::Stage CPDF_ContentParser::Parse() {
  if (!m_pParser) {
    m_ParsedSet.clear();
    m_pParser = std::make_unique<CPDF_StreamContentParser>(
        m_pObjectHolder->GetDocument(),
        m_pObjectHolder->GetMutablePageResources(), nullptr, nullptr,
        m_pObjectHolder.Get(), m_pObjectHolder->GetMutableResources(),
        m_pObjectHolder->GetBBox(), nullptr, &m_ParsedSet);
    m_pParser->GetCurStates()->m_ColorState.SetDefault();
  }
  if (m_CurrentOffset >= GetData().size())
    return Stage::kCheckClip;

  if (m_StreamSegmentOffsets.empty())
    m_StreamSegmentOffsets.push_back(0);

  static constexpr uint32_t kParseStepLimit = 100;
  m_CurrentOffset += m_pParser->Parse(GetData(), m_CurrentOffset,
                                      kParseStepLimit, m_StreamSegmentOffsets);
  return Stage::kParse;
}

CPDF_ContentParser::Stage CPDF_ContentParser::CheckClip() {
  if (m_pType3Char) {
    m_pType3Char->InitializeFromStreamData(m_pParser->IsColored(),
                                           m_pParser->GetType3Data());
  }

  for (auto& pObj : *m_pObjectHolder) {
    if (!pObj->m_ClipPath.HasRef())
      continue;
    if (pObj->m_ClipPath.GetPathCount() != 1)
      continue;
    if (pObj->m_ClipPath.GetTextCount() > 0)
      continue;

    CPDF_Path ClipPath = pObj->m_ClipPath.GetPath(0);
    if (!ClipPath.IsRect() || pObj->IsShading())
      continue;

    CFX_PointF point0 = ClipPath.GetPoint(0);
    CFX_PointF point2 = ClipPath.GetPoint(2);
    CFX_FloatRect old_rect(point0.x, point0.y, point2.x, point2.y);
    if (old_rect.Contains(pObj->GetRect()))
      pObj->m_ClipPath.SetNull();
  }
  return Stage::kComplete;
}

void CPDF_ContentParser::HandlePageContentStream(const CPDF_Stream* pStream) {
  m_pSingleStream =
      pdfium::MakeRetain<CPDF_StreamAcc>(pdfium::WrapRetain(pStream));
  m_pSingleStream->LoadAllDataFiltered();
  m_CurrentStage = Stage::kPrepareContent;
}

bool CPDF_ContentParser::HandlePageContentArray(const CPDF_Array* pArray) {
  m_nStreams = fxcrt::CollectionSize<uint32_t>(*pArray);
  if (m_nStreams == 0)
    return false;

  m_StreamArray.resize(m_nStreams);
  return true;
}

void CPDF_ContentParser::HandlePageContentFailure() {
  m_CurrentStage = Stage::kComplete;
}

pdfium::span<const uint8_t> CPDF_ContentParser::GetData() const {
  if (is_owned()) {
    const OwnedData& data = absl::get<OwnedData>(m_Data);
    return pdfium::make_span(data.buffer.get(), data.size);
  }
  return absl::get<pdfium::span<const uint8_t>>(m_Data);
}
