// Copyright 2017 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_textparser.h"

#include <algorithm>
#include <utility>

#include "core/fxcrt/css/cfx_css.h"
#include "core/fxcrt/css/cfx_csscomputedstyle.h"
#include "core/fxcrt/css/cfx_cssstyleselector.h"
#include "core/fxcrt/css/cfx_cssstylesheet.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/xml/cfx_xmlelement.h"
#include "core/fxcrt/xml/cfx_xmlnode.h"
#include "core/fxge/fx_font.h"
#include "xfa/fgas/font/cfgas_fontmgr.h"
#include "xfa/fgas/font/cfgas_gefont.h"
#include "xfa/fxfa/cxfa_ffapp.h"
#include "xfa/fxfa/cxfa_ffdoc.h"
#include "xfa/fxfa/cxfa_fontmgr.h"
#include "xfa/fxfa/cxfa_textparsecontext.h"
#include "xfa/fxfa/cxfa_textprovider.h"
#include "xfa/fxfa/cxfa_texttabstopscontext.h"
#include "xfa/fxfa/parser/cxfa_font.h"
#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_para.h"

namespace {

enum class TabStopStatus {
  Error,
  EOS,
  None,
  Alignment,
  StartLeader,
  Leader,
  Location,
};

WideString GetLowerCaseElementAttributeOrDefault(
    const CFX_XMLElement* pElement,
    const WideString& wsName,
    const WideString& wsDefaultValue) {
  WideString ws = pElement->GetAttribute(wsName);
  if (ws.IsEmpty())
    ws = wsDefaultValue;
  else
    ws.MakeLower();
  return ws;
}

}  // namespace

CXFA_TextParser::CXFA_TextParser()
    : m_bParsed(false), m_cssInitialized(false) {}

CXFA_TextParser::~CXFA_TextParser() = default;

void CXFA_TextParser::Reset() {
  m_mapXMLNodeToParseContext.clear();
  m_bParsed = false;
}

void CXFA_TextParser::InitCSSData(CXFA_TextProvider* pTextProvider) {
  if (!pTextProvider)
    return;

  if (!m_pSelector) {
    m_pSelector = std::make_unique<CFX_CSSStyleSelector>();

    CXFA_Font* font = pTextProvider->GetFontIfExists();
    m_pSelector->SetDefaultFontSize(font ? font->GetFontSize() : 10.0f);
  }

  if (m_cssInitialized)
    return;

  m_cssInitialized = true;
  auto uaSheet = LoadDefaultSheetStyle();
  m_pSelector->SetUAStyleSheet(std::move(uaSheet));
  m_pSelector->UpdateStyleIndex();
}

std::unique_ptr<CFX_CSSStyleSheet> CXFA_TextParser::LoadDefaultSheetStyle() {
  static const char kStyle[] =
      "html,body,ol,p,ul{display:block}"
      "li{display:list-item}"
      "ol,ul{padding-left:33px;margin:1.12em 0}"
      "ol{list-style-type:decimal}"
      "a{color:#0000ff;text-decoration:underline}"
      "b{font-weight:bolder}"
      "i{font-style:italic}"
      "sup{vertical-align:+15em;font-size:.66em}"
      "sub{vertical-align:-15em;font-size:.66em}";
  WideString ws = WideString::FromASCII(kStyle);
  auto sheet = std::make_unique<CFX_CSSStyleSheet>();
  if (!sheet->LoadBuffer(ws.AsStringView()))
    return nullptr;

  return sheet;
}

RetainPtr<CFX_CSSComputedStyle> CXFA_TextParser::CreateRootStyle(
    CXFA_TextProvider* pTextProvider) {
  CXFA_Para* para = pTextProvider->GetParaIfExists();
  auto pStyle = m_pSelector->CreateComputedStyle(nullptr);
  float fLineHeight = 0;
  float fFontSize = 10;

  if (para) {
    fLineHeight = para->GetLineHeight();
    CFX_CSSLength indent;
    indent.Set(CFX_CSSLengthUnit::Point, para->GetTextIndent());
    pStyle->SetTextIndent(indent);
    CFX_CSSTextAlign hAlign = CFX_CSSTextAlign::Left;
    switch (para->GetHorizontalAlign()) {
      case XFA_AttributeValue::Center:
        hAlign = CFX_CSSTextAlign::Center;
        break;
      case XFA_AttributeValue::Right:
        hAlign = CFX_CSSTextAlign::Right;
        break;
      case XFA_AttributeValue::Justify:
        hAlign = CFX_CSSTextAlign::Justify;
        break;
      case XFA_AttributeValue::JustifyAll:
        hAlign = CFX_CSSTextAlign::JustifyAll;
        break;
      case XFA_AttributeValue::Left:
      case XFA_AttributeValue::Radix:
        break;
      default:
        NOTREACHED();
        break;
    }
    pStyle->SetTextAlign(hAlign);
    CFX_CSSRect rtMarginWidth;
    rtMarginWidth.left.Set(CFX_CSSLengthUnit::Point, para->GetMarginLeft());
    rtMarginWidth.top.Set(CFX_CSSLengthUnit::Point, para->GetSpaceAbove());
    rtMarginWidth.right.Set(CFX_CSSLengthUnit::Point, para->GetMarginRight());
    rtMarginWidth.bottom.Set(CFX_CSSLengthUnit::Point, para->GetSpaceBelow());
    pStyle->SetMarginWidth(rtMarginWidth);
  }

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  if (font) {
    pStyle->SetColor(font->GetColor());
    pStyle->SetFontStyle(font->IsItalic() ? CFX_CSSFontStyle::Italic
                                          : CFX_CSSFontStyle::Normal);
    pStyle->SetFontWeight(font->IsBold() ? FXFONT_FW_BOLD : FXFONT_FW_NORMAL);
    pStyle->SetNumberVerticalAlign(-font->GetBaselineShift());
    fFontSize = font->GetFontSize();
    CFX_CSSLength letterSpacing;
    letterSpacing.Set(CFX_CSSLengthUnit::Point, font->GetLetterSpacing());
    pStyle->SetLetterSpacing(letterSpacing);
    uint32_t dwDecoration = 0;
    if (font->GetLineThrough() > 0)
      dwDecoration |= CFX_CSSTEXTDECORATION_LineThrough;
    if (font->GetUnderline() > 1)
      dwDecoration |= CFX_CSSTEXTDECORATION_Double;
    else if (font->GetUnderline() > 0)
      dwDecoration |= CFX_CSSTEXTDECORATION_Underline;

    pStyle->SetTextDecoration(dwDecoration);
  }
  pStyle->SetLineHeight(fLineHeight);
  pStyle->SetFontSize(fFontSize);
  return pStyle;
}

RetainPtr<CFX_CSSComputedStyle> CXFA_TextParser::CreateStyle(
    CFX_CSSComputedStyle* pParentStyle) {
  auto pNewStyle = m_pSelector->CreateComputedStyle(pParentStyle);
  ASSERT(pNewStyle);
  if (!pParentStyle)
    return pNewStyle;

  uint32_t dwDecoration = pParentStyle->GetTextDecoration();
  float fBaseLine = 0;
  if (pParentStyle->GetVerticalAlign() == CFX_CSSVerticalAlign::Number)
    fBaseLine = pParentStyle->GetNumberVerticalAlign();

  pNewStyle->SetTextDecoration(dwDecoration);
  pNewStyle->SetNumberVerticalAlign(fBaseLine);

  const CFX_CSSRect* pRect = pParentStyle->GetMarginWidth();
  if (pRect)
    pNewStyle->SetMarginWidth(*pRect);
  return pNewStyle;
}

RetainPtr<CFX_CSSComputedStyle> CXFA_TextParser::ComputeStyle(
    const CFX_XMLNode* pXMLNode,
    CFX_CSSComputedStyle* pParentStyle) {
  auto it = m_mapXMLNodeToParseContext.find(pXMLNode);
  if (it == m_mapXMLNodeToParseContext.end())
    return nullptr;

  CXFA_TextParseContext* pContext = it->second.get();
  if (!pContext)
    return nullptr;

  pContext->m_pParentStyle.Reset(pParentStyle);

  auto tagProvider = ParseTagInfo(pXMLNode);
  if (tagProvider->m_bContent)
    return nullptr;

  auto pStyle = CreateStyle(pParentStyle);
  m_pSelector->ComputeStyle(pContext->GetDecls(),
                            tagProvider->GetAttribute(L"style"),
                            tagProvider->GetAttribute(L"align"), pStyle.Get());
  return pStyle;
}

void CXFA_TextParser::DoParse(const CFX_XMLNode* pXMLContainer,
                              CXFA_TextProvider* pTextProvider) {
  if (!pXMLContainer || !pTextProvider || m_bParsed)
    return;

  m_bParsed = true;
  InitCSSData(pTextProvider);
  auto pRootStyle = CreateRootStyle(pTextProvider);
  ParseRichText(pXMLContainer, pRootStyle.Get());
}

void CXFA_TextParser::ParseRichText(const CFX_XMLNode* pXMLNode,
                                    CFX_CSSComputedStyle* pParentStyle) {
  if (!pXMLNode)
    return;

  auto tagProvider = ParseTagInfo(pXMLNode);
  if (!tagProvider->m_bTagAvailable)
    return;

  RetainPtr<CFX_CSSComputedStyle> pNewStyle;
  if (!(tagProvider->GetTagName().EqualsASCII("body") &&
        tagProvider->GetTagName().EqualsASCII("html"))) {
    auto pTextContext = std::make_unique<CXFA_TextParseContext>();
    CFX_CSSDisplay eDisplay = CFX_CSSDisplay::Inline;
    if (!tagProvider->m_bContent) {
      auto declArray =
          m_pSelector->MatchDeclarations(tagProvider->GetTagName());
      pNewStyle = CreateStyle(pParentStyle);
      m_pSelector->ComputeStyle(declArray, tagProvider->GetAttribute(L"style"),
                                tagProvider->GetAttribute(L"align"),
                                pNewStyle.Get());

      if (!declArray.empty())
        pTextContext->SetDecls(std::move(declArray));

      eDisplay = pNewStyle->GetDisplay();
    }
    pTextContext->SetDisplay(eDisplay);
    m_mapXMLNodeToParseContext[pXMLNode] = std::move(pTextContext);
  }

  for (CFX_XMLNode* pXMLChild = pXMLNode->GetFirstChild(); pXMLChild;
       pXMLChild = pXMLChild->GetNextSibling()) {
    ParseRichText(pXMLChild, pNewStyle.Get());
  }
}

bool CXFA_TextParser::TagValidate(const WideString& wsName) const {
  static const uint32_t s_XFATagName[] = {
      0x61,        // a
      0x62,        // b
      0x69,        // i
      0x70,        // p
      0x0001f714,  // br
      0x00022a55,  // li
      0x000239bb,  // ol
      0x00025881,  // ul
      0x0bd37faa,  // sub
      0x0bd37fb8,  // sup
      0xa73e3af2,  // span
      0xb182eaae,  // body
      0xdb8ac455,  // html
  };
  return std::binary_search(std::begin(s_XFATagName), std::end(s_XFATagName),
                            FX_HashCode_GetW(wsName.AsStringView(), true));
}

// static
std::unique_ptr<CXFA_TextParser::TagProvider> CXFA_TextParser::ParseTagInfo(
    const CFX_XMLNode* pXMLNode) {
  auto tagProvider = std::make_unique<TagProvider>();
  const CFX_XMLElement* pXMLElement = ToXMLElement(pXMLNode);
  if (pXMLElement) {
    WideString wsName = pXMLElement->GetLocalTagName();
    tagProvider->SetTagName(wsName);
    tagProvider->m_bTagAvailable = TagValidate(wsName);
    WideString wsValue = pXMLElement->GetAttribute(L"style");
    if (!wsValue.IsEmpty())
      tagProvider->SetAttribute(L"style", wsValue);

    return tagProvider;
  }
  if (pXMLNode->GetType() == CFX_XMLNode::Type::kText) {
    tagProvider->m_bTagAvailable = true;
    tagProvider->m_bContent = true;
  }
  return tagProvider;
}

XFA_AttributeValue CXFA_TextParser::GetVAlign(
    CXFA_TextProvider* pTextProvider) const {
  CXFA_Para* para = pTextProvider->GetParaIfExists();
  return para ? para->GetVerticalAlign() : XFA_AttributeValue::Top;
}

float CXFA_TextParser::GetTabInterval(CFX_CSSComputedStyle* pStyle) const {
  WideString wsValue;
  if (pStyle && pStyle->GetCustomStyle(L"tab-interval", &wsValue))
    return CXFA_Measurement(wsValue.AsStringView()).ToUnit(XFA_Unit::Pt);
  return 36;
}

int32_t CXFA_TextParser::CountTabs(CFX_CSSComputedStyle* pStyle) const {
  WideString wsValue;
  if (pStyle && pStyle->GetCustomStyle(L"xfa-tab-count", &wsValue))
    return wsValue.GetInteger();
  return 0;
}

bool CXFA_TextParser::IsSpaceRun(CFX_CSSComputedStyle* pStyle) const {
  WideString wsValue;
  return pStyle && pStyle->GetCustomStyle(L"xfa-spacerun", &wsValue) &&
         wsValue.EqualsASCIINoCase("yes");
}

RetainPtr<CFGAS_GEFont> CXFA_TextParser::GetFont(
    CXFA_FFDoc* doc,
    CXFA_TextProvider* pTextProvider,
    CFX_CSSComputedStyle* pStyle) const {
  WideString wsFamily = L"Courier";
  uint32_t dwStyle = 0;
  CXFA_Font* font = pTextProvider->GetFontIfExists();
  if (font) {
    wsFamily = font->GetTypeface();
    if (font->IsBold())
      dwStyle |= FXFONT_FORCE_BOLD;
    if (font->IsItalic())
      dwStyle |= FXFONT_FORCE_BOLD;
  }

  if (pStyle) {
    int32_t iCount = pStyle->CountFontFamilies();
    if (iCount > 0)
      wsFamily = pStyle->GetFontFamily(iCount - 1).AsStringView();

    dwStyle = 0;
    if (pStyle->GetFontWeight() > FXFONT_FW_NORMAL)
      dwStyle |= FXFONT_FORCE_BOLD;
    if (pStyle->GetFontStyle() == CFX_CSSFontStyle::Italic)
      dwStyle |= FXFONT_ITALIC;
  }

  CXFA_FontMgr* pFontMgr = doc->GetApp()->GetXFAFontMgr();
  return pFontMgr->GetFont(doc, wsFamily.AsStringView(), dwStyle);
}

float CXFA_TextParser::GetFontSize(CXFA_TextProvider* pTextProvider,
                                   CFX_CSSComputedStyle* pStyle) const {
  if (pStyle)
    return pStyle->GetFontSize();

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? font->GetFontSize() : 10;
}

int32_t CXFA_TextParser::GetHorScale(CXFA_TextProvider* pTextProvider,
                                     CFX_CSSComputedStyle* pStyle,
                                     const CFX_XMLNode* pXMLNode) const {
  if (pStyle) {
    WideString wsValue;
    if (pStyle->GetCustomStyle(L"xfa-font-horizontal-scale", &wsValue))
      return wsValue.GetInteger();

    while (pXMLNode) {
      auto it = m_mapXMLNodeToParseContext.find(pXMLNode);
      if (it != m_mapXMLNodeToParseContext.end()) {
        CXFA_TextParseContext* pContext = it->second.get();
        if (pContext && pContext->m_pParentStyle &&
            pContext->m_pParentStyle->GetCustomStyle(
                L"xfa-font-horizontal-scale", &wsValue)) {
          return wsValue.GetInteger();
        }
      }
      pXMLNode = pXMLNode->GetParent();
    }
  }

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? static_cast<int32_t>(font->GetHorizontalScale()) : 100;
}

int32_t CXFA_TextParser::GetVerScale(CXFA_TextProvider* pTextProvider,
                                     CFX_CSSComputedStyle* pStyle) const {
  if (pStyle) {
    WideString wsValue;
    if (pStyle->GetCustomStyle(L"xfa-font-vertical-scale", &wsValue))
      return wsValue.GetInteger();
  }

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? static_cast<int32_t>(font->GetVerticalScale()) : 100;
}

void CXFA_TextParser::GetUnderline(CXFA_TextProvider* pTextProvider,
                                   CFX_CSSComputedStyle* pStyle,
                                   int32_t& iUnderline,
                                   XFA_AttributeValue& iPeriod) const {
  iUnderline = 0;
  iPeriod = XFA_AttributeValue::All;
  CXFA_Font* font = pTextProvider->GetFontIfExists();
  if (!pStyle) {
    if (font) {
      iUnderline = font->GetUnderline();
      iPeriod = font->GetUnderlinePeriod();
    }
    return;
  }

  uint32_t dwDecoration = pStyle->GetTextDecoration();
  if (dwDecoration & CFX_CSSTEXTDECORATION_Double)
    iUnderline = 2;
  else if (dwDecoration & CFX_CSSTEXTDECORATION_Underline)
    iUnderline = 1;

  WideString wsValue;
  if (pStyle->GetCustomStyle(L"underlinePeriod", &wsValue)) {
    if (wsValue.EqualsASCII("word"))
      iPeriod = XFA_AttributeValue::Word;
  } else if (font) {
    iPeriod = font->GetUnderlinePeriod();
  }
}

void CXFA_TextParser::GetLinethrough(CXFA_TextProvider* pTextProvider,
                                     CFX_CSSComputedStyle* pStyle,
                                     int32_t& iLinethrough) const {
  iLinethrough = 0;
  if (pStyle) {
    uint32_t dwDecoration = pStyle->GetTextDecoration();
    if (dwDecoration & CFX_CSSTEXTDECORATION_LineThrough)
      iLinethrough = 1;
    return;
  }

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  if (font)
    iLinethrough = font->GetLineThrough();
}

FX_ARGB CXFA_TextParser::GetColor(CXFA_TextProvider* pTextProvider,
                                  CFX_CSSComputedStyle* pStyle) const {
  if (pStyle)
    return pStyle->GetColor();

  CXFA_Font* font = pTextProvider->GetFontIfExists();
  return font ? font->GetColor() : 0xFF000000;
}

float CXFA_TextParser::GetBaseline(CXFA_TextProvider* pTextProvider,
                                   CFX_CSSComputedStyle* pStyle) const {
  if (pStyle) {
    if (pStyle->GetVerticalAlign() == CFX_CSSVerticalAlign::Number)
      return pStyle->GetNumberVerticalAlign();
  } else {
    CXFA_Font* font = pTextProvider->GetFontIfExists();
    if (font)
      return font->GetBaselineShift();
  }
  return 0;
}

float CXFA_TextParser::GetLineHeight(CXFA_TextProvider* pTextProvider,
                                     CFX_CSSComputedStyle* pStyle,
                                     bool bFirst,
                                     float fVerScale) const {
  float fLineHeight = 0;
  if (pStyle) {
    fLineHeight = pStyle->GetLineHeight();
  } else {
    CXFA_Para* para = pTextProvider->GetParaIfExists();
    if (para)
      fLineHeight = para->GetLineHeight();
  }

  if (bFirst) {
    float fFontSize = GetFontSize(pTextProvider, pStyle);
    if (fLineHeight < 0.1f)
      fLineHeight = fFontSize;
    else
      fLineHeight = std::min(fLineHeight, fFontSize);
  } else if (fLineHeight < 0.1f) {
    fLineHeight = GetFontSize(pTextProvider, pStyle) * 1.2f;
  }
  fLineHeight *= fVerScale;
  return fLineHeight;
}

Optional<WideString> CXFA_TextParser::GetEmbeddedObj(
    const CXFA_TextProvider* pTextProvider,
    const CFX_XMLNode* pXMLNode) {
  if (!pXMLNode)
    return {};

  const CFX_XMLElement* pElement = ToXMLElement(pXMLNode);
  if (!pElement)
    return {};

  WideString wsAttr = pElement->GetAttribute(L"xfa:embed");
  if (wsAttr.IsEmpty())
    return {};

  if (wsAttr[0] == L'#')
    wsAttr.Delete(0);

  WideString ws =
      GetLowerCaseElementAttributeOrDefault(pElement, L"xfa:embedType", L"som");
  if (!ws.EqualsASCII("uri"))
    return {};

  ws = GetLowerCaseElementAttributeOrDefault(pElement, L"xfa:embedMode",
                                             L"formatted");
  if (!(ws.EqualsASCII("raw") || ws.EqualsASCII("formatted")))
    return {};

  return pTextProvider->GetEmbeddedObj(wsAttr);
}

CXFA_TextParseContext* CXFA_TextParser::GetParseContextFromMap(
    const CFX_XMLNode* pXMLNode) {
  auto it = m_mapXMLNodeToParseContext.find(pXMLNode);
  return it != m_mapXMLNodeToParseContext.end() ? it->second.get() : nullptr;
}

bool CXFA_TextParser::GetTabstops(CFX_CSSComputedStyle* pStyle,
                                  CXFA_TextTabstopsContext* pTabstopContext) {
  if (!pStyle || !pTabstopContext)
    return false;

  WideString wsValue;
  if (!pStyle->GetCustomStyle(L"xfa-tab-stops", &wsValue) &&
      !pStyle->GetCustomStyle(L"tab-stops", &wsValue)) {
    return false;
  }

  pdfium::span<const wchar_t> spTabStops = wsValue.span();
  size_t iCur = 0;
  size_t iLast = 0;
  WideString wsAlign;
  TabStopStatus eStatus = TabStopStatus::None;
  while (iCur < spTabStops.size()) {
    wchar_t ch = spTabStops[iCur];
    switch (eStatus) {
      case TabStopStatus::None:
        if (ch <= ' ') {
          iCur++;
        } else {
          eStatus = TabStopStatus::Alignment;
          iLast = iCur;
        }
        break;
      case TabStopStatus::Alignment:
        if (ch == ' ') {
          wsAlign = WideStringView(spTabStops.subspan(iLast, iCur - iLast));
          eStatus = TabStopStatus::StartLeader;
          iCur++;
          while (iCur < spTabStops.size() && spTabStops[iCur] <= ' ')
            iCur++;
          iLast = iCur;
        } else {
          iCur++;
        }
        break;
      case TabStopStatus::StartLeader:
        if (ch != 'l') {
          eStatus = TabStopStatus::Location;
        } else {
          int32_t iCount = 0;
          while (iCur < spTabStops.size()) {
            ch = spTabStops[iCur];
            iCur++;
            if (ch == '(') {
              iCount++;
            } else if (ch == ')') {
              iCount--;
              if (iCount == 0)
                break;
            }
          }
          while (iCur < spTabStops.size() && spTabStops[iCur] <= ' ')
            iCur++;

          iLast = iCur;
          eStatus = TabStopStatus::Location;
        }
        break;
      case TabStopStatus::Location:
        if (ch == ' ') {
          uint32_t dwHashCode = FX_HashCode_GetW(wsAlign.AsStringView(), true);
          CXFA_Measurement ms(
              WideStringView(spTabStops.subspan(iLast, iCur - iLast)));
          float fPos = ms.ToUnit(XFA_Unit::Pt);
          pTabstopContext->Append(dwHashCode, fPos);
          wsAlign.clear();
          eStatus = TabStopStatus::None;
        }
        iCur++;
        break;
      default:
        break;
    }
  }

  if (!wsAlign.IsEmpty()) {
    uint32_t dwHashCode = FX_HashCode_GetW(wsAlign.AsStringView(), true);
    CXFA_Measurement ms(
        WideStringView(spTabStops.subspan(iLast, iCur - iLast)));
    float fPos = ms.ToUnit(XFA_Unit::Pt);
    pTabstopContext->Append(dwHashCode, fPos);
  }
  return true;
}

CXFA_TextParser::TagProvider::TagProvider()
    : m_bTagAvailable(false), m_bContent(false) {}

CXFA_TextParser::TagProvider::~TagProvider() = default;
