// 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 "third_party/base/compiler_specific.h"
#include "third_party/base/logging.h"

namespace {

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

}  // namespace

CFX_CSSSyntaxParser::CFX_CSSSyntaxParser(const wchar_t* pBuffer,
                                         int32_t iBufferSize) {
  ASSERT(pBuffer);
  m_Output.InitWithSize(32);
  m_Input.AttachBuffer(pBuffer, iBufferSize);
}

CFX_CSSSyntaxParser::~CFX_CSSSyntaxParser() = default;

void CFX_CSSSyntaxParser::SetParseOnlyDeclarations() {
  m_eMode = SyntaxMode::kPropertyName;
}

CFX_CSSSyntaxStatus CFX_CSSSyntaxParser::DoSyntaxParse() {
  m_Output.Clear();
  if (m_bError)
    return CFX_CSSSyntaxStatus::kError;

  while (!m_Input.IsEOF()) {
    wchar_t wch = m_Input.GetChar();
    switch (m_eMode) {
      case SyntaxMode::kRuleSet:
        switch (wch) {
          case '}':
            m_bError = true;
            return CFX_CSSSyntaxStatus::kError;
          case '/':
            if (m_Input.GetNextChar() == '*') {
              m_ModeStack.push(m_eMode);
              SwitchMode(SyntaxMode::kComment);
              break;
            }
            FALLTHROUGH;
          default:
            if (wch <= ' ') {
              m_Input.MoveNext();
            } else if (IsSelectorStart(wch)) {
              SwitchMode(SyntaxMode::kSelector);
              return CFX_CSSSyntaxStatus::kStyleRule;
            } else {
              m_bError = true;
              return CFX_CSSSyntaxStatus::kError;
            }
            break;
        }
        break;
      case SyntaxMode::kSelector:
        switch (wch) {
          case ',':
            m_Input.MoveNext();
            SwitchMode(SyntaxMode::kSelector);
            if (m_Output.GetLength() > 0)
              return CFX_CSSSyntaxStatus::kSelector;
            break;
          case '{':
            if (m_Output.GetLength() > 0) {
              SaveTextData();
              return CFX_CSSSyntaxStatus::kSelector;
            }
            m_Input.MoveNext();
            m_ModeStack.push(SyntaxMode::kRuleSet);
            SwitchMode(SyntaxMode::kPropertyName);
            return CFX_CSSSyntaxStatus::kDeclOpen;
          case '/':
            if (m_Input.GetNextChar() == '*') {
              if (SwitchToComment() > 0)
                return CFX_CSSSyntaxStatus::kSelector;
              break;
            }
            FALLTHROUGH;
          default:
            AppendCharIfNotLeadingBlank(wch);
            m_Input.MoveNext();
            break;
        }
        break;
      case SyntaxMode::kPropertyName:
        switch (wch) {
          case ':':
            m_Input.MoveNext();
            SwitchMode(SyntaxMode::kPropertyValue);
            return CFX_CSSSyntaxStatus::kPropertyName;
          case '}':
            m_Input.MoveNext();
            if (RestoreMode())
              return CFX_CSSSyntaxStatus::kDeclClose;

            m_bError = true;
            return CFX_CSSSyntaxStatus::kError;
          case '/':
            if (m_Input.GetNextChar() == '*') {
              if (SwitchToComment() > 0)
                return CFX_CSSSyntaxStatus::kPropertyName;
              break;
            }
            FALLTHROUGH;
          default:
            AppendCharIfNotLeadingBlank(wch);
            m_Input.MoveNext();
            break;
        }
        break;
      case SyntaxMode::kPropertyValue:
        switch (wch) {
          case ';':
            m_Input.MoveNext();
            FALLTHROUGH;
          case '}':
            SwitchMode(SyntaxMode::kPropertyName);
            return CFX_CSSSyntaxStatus::kPropertyValue;
          case '/':
            if (m_Input.GetNextChar() == '*') {
              if (SwitchToComment() > 0)
                return CFX_CSSSyntaxStatus::kPropertyValue;
              break;
            }
            FALLTHROUGH;
          default:
            AppendCharIfNotLeadingBlank(wch);
            m_Input.MoveNext();
            break;
        }
        break;
      case SyntaxMode::kComment:
        if (wch == '*' && m_Input.GetNextChar() == '/') {
          RestoreMode();
          m_Input.MoveNext();
        }
        m_Input.MoveNext();
        break;
      default:
        NOTREACHED();
        break;
    }
  }
  if (m_eMode == SyntaxMode::kPropertyValue && m_Output.GetLength() > 0) {
    SaveTextData();
    return CFX_CSSSyntaxStatus::kPropertyValue;
  }
  return CFX_CSSSyntaxStatus::kEOS;
}

void CFX_CSSSyntaxParser::AppendCharIfNotLeadingBlank(wchar_t wch) {
  if (m_Output.GetLength() > 0 || wch > ' ')
    m_Output.AppendChar(wch);
}

void CFX_CSSSyntaxParser::SaveTextData() {
  m_Output.TrimEnd();
}

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

int32_t CFX_CSSSyntaxParser::SwitchToComment() {
  int32_t iLength = m_Output.GetLength();
  m_ModeStack.push(m_eMode);
  SwitchMode(SyntaxMode::kComment);
  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_Output.GetBuffer(), m_Output.GetLength());
}
