// 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 "core/fxcrt/css/cfx_csssyntaxparser.h"

#include <algorithm>

#include "core/fxcrt/css/cfx_cssdata.h"
#include "core/fxcrt/css/cfx_cssdeclaration.h"
#include "core/fxcrt/fx_codepage.h"
#include "core/fxcrt/fx_extension.h"
#include "core/fxcrt/fx_fallthrough.h"
#include "third_party/base/logging.h"

namespace {

bool IsSelectorStart(wchar_t wch) {
  return wch == '.' || wch == '#' || wch == '*' || FXSYS_iswalpha(wch);
}

}  // namespace

CFX_CSSSyntaxParser::CFX_CSSSyntaxParser(const wchar_t* pBuffer,
                                         int32_t iBufferSize)
    : CFX_CSSSyntaxParser(pBuffer, iBufferSize, 32, false) {}

CFX_CSSSyntaxParser::CFX_CSSSyntaxParser(const wchar_t* pBuffer,
                                         int32_t iBufferSize,
                                         int32_t iTextDatSize,
                                         bool bOnlyDeclaration)
    : m_iTextDataLen(0),
      m_dwCheck(0xFFFFFFFF),
      m_eStatus(CFX_CSSSyntaxStatus::None) {
  ASSERT(pBuffer && iBufferSize > 0 && iTextDatSize > 0);
  m_eMode = bOnlyDeclaration ? CFX_CSSSyntaxMode::PropertyName
                             : CFX_CSSSyntaxMode::RuleSet;
  m_TextData.InitWithSize(iTextDatSize);
  m_TextPlane.AttachBuffer(pBuffer, iBufferSize);
}

CFX_CSSSyntaxParser::~CFX_CSSSyntaxParser() {}

CFX_CSSSyntaxStatus CFX_CSSSyntaxParser::DoSyntaxParse() {
  while (m_eStatus >= CFX_CSSSyntaxStatus::None) {
    if (m_TextPlane.IsEOF()) {
      if (m_eMode == CFX_CSSSyntaxMode::PropertyValue &&
          m_TextData.GetLength() > 0) {
        SaveTextData();
        m_eStatus = CFX_CSSSyntaxStatus::PropertyValue;
        return m_eStatus;
      }
      m_eStatus = CFX_CSSSyntaxStatus::EOS;
      return m_eStatus;
    }
    wchar_t wch;
    while (!m_TextPlane.IsEOF()) {
      wch = m_TextPlane.GetChar();
      switch (m_eMode) {
        case CFX_CSSSyntaxMode::RuleSet:
          switch (wch) {
            case '}':
              m_TextPlane.MoveNext();
              if (RestoreMode())
                return CFX_CSSSyntaxStatus::DeclClose;

              m_eStatus = CFX_CSSSyntaxStatus::Error;
              return m_eStatus;
            case '/':
              if (m_TextPlane.GetNextChar() == '*') {
                m_ModeStack.push(m_eMode);
                SwitchMode(CFX_CSSSyntaxMode::Comment);
                break;
              }
              FX_FALLTHROUGH;
            default:
              if (wch <= ' ') {
                m_TextPlane.MoveNext();
              } else if (IsSelectorStart(wch)) {
                SwitchMode(CFX_CSSSyntaxMode::Selector);
                return CFX_CSSSyntaxStatus::StyleRule;
              } else {
                m_eStatus = CFX_CSSSyntaxStatus::Error;
                return m_eStatus;
              }
              break;
          }
          break;
        case CFX_CSSSyntaxMode::Selector:
          switch (wch) {
            case ',':
              m_TextPlane.MoveNext();
              SwitchMode(CFX_CSSSyntaxMode::Selector);
              if (m_iTextDataLen > 0)
                return CFX_CSSSyntaxStatus::Selector;
              break;
            case '{':
              if (m_TextData.GetLength() > 0) {
                SaveTextData();
                return CFX_CSSSyntaxStatus::Selector;
              }
              m_TextPlane.MoveNext();
              m_ModeStack.push(CFX_CSSSyntaxMode::RuleSet);
              SwitchMode(CFX_CSSSyntaxMode::PropertyName);
              return CFX_CSSSyntaxStatus::DeclOpen;
            case '/':
              if (m_TextPlane.GetNextChar() == '*') {
                if (SwitchToComment() > 0)
                  return CFX_CSSSyntaxStatus::Selector;
                break;
              }
              FX_FALLTHROUGH;
            default:
              AppendChar(wch);
              break;
          }
          break;
        case CFX_CSSSyntaxMode::PropertyName:
          switch (wch) {
            case ':':
              m_TextPlane.MoveNext();
              SwitchMode(CFX_CSSSyntaxMode::PropertyValue);
              return CFX_CSSSyntaxStatus::PropertyName;
            case '}':
              m_TextPlane.MoveNext();
              if (RestoreMode())
                return CFX_CSSSyntaxStatus::DeclClose;

              m_eStatus = CFX_CSSSyntaxStatus::Error;
              return m_eStatus;
            case '/':
              if (m_TextPlane.GetNextChar() == '*') {
                if (SwitchToComment() > 0)
                  return CFX_CSSSyntaxStatus::PropertyName;
                break;
              }
              FX_FALLTHROUGH;
            default:
              AppendChar(wch);
              break;
          }
          break;
        case CFX_CSSSyntaxMode::PropertyValue:
          switch (wch) {
            case ';':
              m_TextPlane.MoveNext();
              FX_FALLTHROUGH;
            case '}':
              SwitchMode(CFX_CSSSyntaxMode::PropertyName);
              return CFX_CSSSyntaxStatus::PropertyValue;
            case '/':
              if (m_TextPlane.GetNextChar() == '*') {
                if (SwitchToComment() > 0)
                  return CFX_CSSSyntaxStatus::PropertyValue;
                break;
              }
              FX_FALLTHROUGH;
            default:
              AppendChar(wch);
              break;
          }
          break;
        case CFX_CSSSyntaxMode::Comment:
          if (wch == '/' && m_TextData.GetLength() > 0 &&
              m_TextData.GetBuffer()[m_TextData.GetLength() - 1] == '*') {
            RestoreMode();
          } else {
            m_TextData.AppendChar(wch);
          }
          m_TextPlane.MoveNext();
          break;
        case CFX_CSSSyntaxMode::UnknownRule:
          if (wch == ';')
            SwitchMode(CFX_CSSSyntaxMode::RuleSet);
          m_TextPlane.MoveNext();
          break;
        default:
          NOTREACHED();
          break;
      }
    }
  }
  return m_eStatus;
}

bool CFX_CSSSyntaxParser::IsImportEnabled() const {
  if ((m_dwCheck & CFX_CSSSYNTAXCHECK_AllowImport) == 0)
    return false;
  if (m_ModeStack.size() > 1)
    return false;
  return true;
}

bool CFX_CSSSyntaxParser::AppendChar(wchar_t wch) {
  m_TextPlane.MoveNext();
  if (m_TextData.GetLength() > 0 || wch > ' ') {
    m_TextData.AppendChar(wch);
    return true;
  }
  return false;
}

int32_t CFX_CSSSyntaxParser::SaveTextData() {
  m_iTextDataLen = m_TextData.TrimEnd();
  m_TextData.Clear();
  return m_iTextDataLen;
}

void CFX_CSSSyntaxParser::SwitchMode(CFX_CSSSyntaxMode eMode) {
  m_eMode = eMode;
  SaveTextData();
}

int32_t CFX_CSSSyntaxParser::SwitchToComment() {
  int32_t iLength = m_TextData.GetLength();
  m_ModeStack.push(m_eMode);
  SwitchMode(CFX_CSSSyntaxMode::Comment);
  return iLength;
}

bool CFX_CSSSyntaxParser::RestoreMode() {
  if (m_ModeStack.empty())
    return false;

  SwitchMode(m_ModeStack.top());
  m_ModeStack.pop();
  return true;
}

WideStringView CFX_CSSSyntaxParser::GetCurrentString() const {
  return WideStringView(m_TextData.GetBuffer(), m_iTextDataLen);
}
