// Copyright 2015 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/parser/css_variable_parser.h"

#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
#include "third_party/blink/renderer/core/css/css_variable_reference_value.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"

namespace blink {

namespace {

bool IsValidVariableReference(CSSParserTokenRange);
bool IsValidEnvVariableReference(CSSParserTokenRange);

bool ClassifyBlock(CSSParserTokenRange range, bool& has_references) {
  size_t block_stack_size = 0;

  while (!range.AtEnd()) {
    // First check if this is a valid variable reference, then handle the next
    // token accordingly.
    if (range.Peek().GetBlockType() == CSSParserToken::kBlockStart) {
      const CSSParserToken& token = range.Peek();

      // A block may have both var and env references. They can also be nested
      // and used as fallbacks.
      switch (token.FunctionId()) {
        case CSSValueID::kVar:
          if (!IsValidVariableReference(range.ConsumeBlock()))
            return false;  // Invalid reference.
          has_references = true;
          continue;
        case CSSValueID::kEnv:
          if (!IsValidEnvVariableReference(range.ConsumeBlock()))
            return false;  // Invalid reference.
          has_references = true;
          continue;
        default:
          break;
      }
    }

    const CSSParserToken& token = range.Consume();
    if (token.GetBlockType() == CSSParserToken::kBlockStart) {
      ++block_stack_size;
    } else if (token.GetBlockType() == CSSParserToken::kBlockEnd) {
      --block_stack_size;
    } else {
      switch (token.GetType()) {
        case kDelimiterToken: {
          if (token.Delimiter() == '!' && block_stack_size == 0)
            return false;
          break;
        }
        case kRightParenthesisToken:
        case kRightBraceToken:
        case kRightBracketToken:
        case kBadStringToken:
        case kBadUrlToken:
          return false;
        case kSemicolonToken:
          if (block_stack_size == 0)
            return false;
          break;
        default:
          break;
      }
    }
  }
  return true;
}

bool IsValidVariableReference(CSSParserTokenRange range) {
  range.ConsumeWhitespace();
  if (!CSSVariableParser::IsValidVariableName(
          range.ConsumeIncludingWhitespace()))
    return false;
  if (range.AtEnd())
    return true;

  if (range.Consume().GetType() != kCommaToken)
    return false;
  if (range.AtEnd())
    return false;

  bool has_references = false;
  return ClassifyBlock(range, has_references);
}

bool IsValidEnvVariableReference(CSSParserTokenRange range) {
  range.ConsumeWhitespace();
  if (range.ConsumeIncludingWhitespace().GetType() !=
      CSSParserTokenType::kIdentToken)
    return false;
  if (range.AtEnd())
    return true;

  if (range.Consume().GetType() != kCommaToken)
    return false;
  if (range.AtEnd())
    return false;

  bool has_references = false;
  return ClassifyBlock(range, has_references);
}

CSSValueID ClassifyVariableRange(CSSParserTokenRange range,
                                 bool& has_references) {
  has_references = false;

  range.ConsumeWhitespace();
  if (range.Peek().GetType() == kIdentToken) {
    CSSValueID id = range.ConsumeIncludingWhitespace().Id();
    if (range.AtEnd() && css_parsing_utils::IsCSSWideKeyword(id))
      return id;
  }

  if (ClassifyBlock(range, has_references))
    return CSSValueID::kInternalVariableValue;
  return CSSValueID::kInvalid;
}

}  // namespace

bool CSSVariableParser::IsValidVariableName(const CSSParserToken& token) {
  if (token.GetType() != kIdentToken)
    return false;

  StringView value = token.Value();
  return value.length() >= 2 && value[0] == '-' && value[1] == '-';
}

bool CSSVariableParser::IsValidVariableName(const String& string) {
  return string.length() >= 2 && string[0] == '-' && string[1] == '-';
}

bool CSSVariableParser::ContainsValidVariableReferences(
    CSSParserTokenRange range) {
  bool has_references;
  CSSValueID type = ClassifyVariableRange(range, has_references);
  return type == CSSValueID::kInternalVariableValue && has_references;
}

CSSCustomPropertyDeclaration* CSSVariableParser::ParseDeclarationValue(
    const AtomicString& variable_name,
    const CSSTokenizedValue& tokenized_value,
    bool is_animation_tainted,
    const CSSParserContext& context) {
  if (tokenized_value.range.AtEnd())
    return nullptr;

  bool has_references;
  CSSValueID type =
      ClassifyVariableRange(tokenized_value.range, has_references);

  if (!IsValidCSSValueID(type))
    return nullptr;
  if (type == CSSValueID::kInternalVariableValue) {
    return MakeGarbageCollected<CSSCustomPropertyDeclaration>(
        variable_name,
        CSSVariableData::Create(tokenized_value, is_animation_tainted,
                                has_references, context.BaseURL(),
                                context.Charset()));
  }
  return MakeGarbageCollected<CSSCustomPropertyDeclaration>(variable_name,
                                                            type);
}

CSSVariableReferenceValue* CSSVariableParser::ParseRegisteredPropertyValue(
    CSSParserTokenRange range,
    const CSSParserContext& context,
    bool require_var_reference,
    bool is_animation_tainted) {
  if (range.AtEnd())
    return nullptr;

  bool has_references;
  CSSValueID type = ClassifyVariableRange(range, has_references);

  if (type != CSSValueID::kInternalVariableValue)
    return nullptr;  // Invalid or a css-wide keyword
  if (require_var_reference && !has_references)
    return nullptr;
  return MakeGarbageCollected<CSSVariableReferenceValue>(
      CSSVariableData::Create({range, StringView()}, is_animation_tainted,
                              has_references, context.BaseURL(),
                              context.Charset()),
      context);
}

}  // namespace blink
