// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "third_party/blink/renderer/core/css/css_syntax_string_parser.h"

#include <utility>
#include "third_party/blink/renderer/core/css/css_syntax_component.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_idioms.h"
#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/html/parser/html_parser_idioms.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"

namespace blink {

namespace {

// https://drafts.css-houdini.org/css-properties-values-api-1/#supported-names
base::Optional<CSSSyntaxType> ParseSyntaxType(StringView type) {
  if (type == "length")
    return CSSSyntaxType::kLength;
  if (type == "number")
    return CSSSyntaxType::kNumber;
  if (type == "percentage")
    return CSSSyntaxType::kPercentage;
  if (type == "length-percentage")
    return CSSSyntaxType::kLengthPercentage;
  if (type == "color")
    return CSSSyntaxType::kColor;
  if (RuntimeEnabledFeatures::CSSVariables2ImageValuesEnabled()) {
    if (type == "image")
      return CSSSyntaxType::kImage;
  }
  if (type == "url")
    return CSSSyntaxType::kUrl;
  if (type == "integer")
    return CSSSyntaxType::kInteger;
  if (type == "angle")
    return CSSSyntaxType::kAngle;
  if (type == "time")
    return CSSSyntaxType::kTime;
  if (type == "resolution")
    return CSSSyntaxType::kResolution;
  if (RuntimeEnabledFeatures::CSSVariables2TransformValuesEnabled()) {
    if (type == "transform-function")
      return CSSSyntaxType::kTransformFunction;
    if (type == "transform-list")
      return CSSSyntaxType::kTransformList;
  }
  if (type == "custom-ident")
    return CSSSyntaxType::kCustomIdent;
  return base::nullopt;
}

bool IsPreMultiplied(CSSSyntaxType type) {
  return type == CSSSyntaxType::kTransformList;
}

}  // namespace

CSSSyntaxStringParser::CSSSyntaxStringParser(const String& string)
    : string_(string.StripWhiteSpace()), input_(string_) {}

base::Optional<CSSSyntaxDefinition> CSSSyntaxStringParser::Parse() {
  if (string_.IsEmpty())
    return base::nullopt;
  if (string_.length() == 1 && string_[0] == '*')
    return CSSSyntaxDefinition::CreateUniversal();

  Vector<CSSSyntaxComponent> components;

  while (true) {
    if (!ConsumeSyntaxComponent(components))
      return base::nullopt;
    input_.AdvanceUntilNonWhitespace();
    UChar cc = input_.NextInputChar();
    input_.Advance();
    if (cc == '\0')
      break;
    if (cc == '|')
      continue;
    return base::nullopt;
  }

  return CSSSyntaxDefinition(std::move(components));
}

bool CSSSyntaxStringParser::ConsumeSyntaxComponent(
    Vector<CSSSyntaxComponent>& components) {
  input_.AdvanceUntilNonWhitespace();

  CSSSyntaxType type = CSSSyntaxType::kTokenStream;
  String ident;

  UChar cc = input_.NextInputChar();
  input_.Advance();

  if (cc == '<') {
    if (!ConsumeDataTypeName(type))
      return false;
  } else if (IsNameStartCodePoint(cc) || cc == '\\') {
    if (NextCharsAreIdentifier(cc, input_)) {
      input_.PushBack(cc);
      type = CSSSyntaxType::kIdent;
      if (!ConsumeIdent(ident))
        return false;
    }
  } else {
    return false;
  }

  DCHECK_NE(type, CSSSyntaxType::kTokenStream);

  CSSSyntaxRepeat repeat =
      IsPreMultiplied(type) ? CSSSyntaxRepeat::kNone : ConsumeRepeatIfPresent();
  components.emplace_back(type, ident, repeat);
  return true;
}

CSSSyntaxRepeat CSSSyntaxStringParser::ConsumeRepeatIfPresent() {
  UChar cc = input_.NextInputChar();
  if (cc == '+') {
    input_.Advance();
    return CSSSyntaxRepeat::kSpaceSeparated;
  }
  if (cc == '#') {
    input_.Advance();
    return CSSSyntaxRepeat::kCommaSeparated;
  }
  return CSSSyntaxRepeat::kNone;
}

bool CSSSyntaxStringParser::ConsumeDataTypeName(CSSSyntaxType& type) {
  for (unsigned size = 0;; ++size) {
    UChar cc = input_.PeekWithoutReplacement(size);
    if (IsNameCodePoint(cc))
      continue;
    if (cc == '>') {
      unsigned start = input_.Offset();
      input_.Advance(size + 1);
      if (auto syntax_type = ParseSyntaxType(input_.RangeAt(start, size))) {
        type = *syntax_type;
        return true;
      }
      return false;
    }
    return false;
  }
}

bool CSSSyntaxStringParser::ConsumeIdent(String& ident) {
  ident = ConsumeName(input_);
  // TODO(crbug.com/882285): Make 'default' invalid as <custom-ident>.
  return !css_parsing_utils::IsCSSWideKeyword(ident) &&
         !css_parsing_utils::IsRevertKeyword(ident) &&
         !css_parsing_utils::IsDefaultKeyword(ident);
}

}  // namespace blink
