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

#include "third_party/blink/renderer/core/css/css_custom_property_declaration.h"
#include "third_party/blink/renderer/core/css/css_font_face_src_value.h"
#include "third_party/blink/renderer/core/css/css_id_selector_value.h"
#include "third_party/blink/renderer/core/css/css_string_value.h"
#include "third_party/blink/renderer/core/css/css_unicode_range_value.h"
#include "third_party/blink/renderer/core/css/css_value.h"
#include "third_party/blink/renderer/core/css/css_value_pair.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_mode.h"
#include "third_party/blink/renderer/core/css/parser/css_parser_token_range.h"
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/css/parser/css_variable_parser.h"
#include "third_party/blink/renderer/core/css/properties/css_parsing_utils.h"
#include "third_party/blink/renderer/core/css/properties/css_property.h"

namespace blink {

namespace {

CSSValue* ConsumeFontVariantList(CSSParserTokenRange& range) {
  CSSValueList* values = CSSValueList::CreateCommaSeparated();
  do {
    if (range.Peek().Id() == CSSValueID::kAll) {
      // FIXME: CSSPropertyParser::ParseFontVariant() implements
      // the old css3 draft:
      // http://www.w3.org/TR/2002/WD-css3-webfonts-20020802/#font-variant
      // 'all' is only allowed in @font-face and with no other values.
      if (values->length())
        return nullptr;
      return css_parsing_utils::ConsumeIdent(range);
    }
    CSSIdentifierValue* font_variant =
        css_parsing_utils::ConsumeFontVariantCSS21(range);
    if (font_variant)
      values->Append(*font_variant);
  } while (css_parsing_utils::ConsumeCommaIncludingWhitespace(range));

  if (values->length())
    return values;

  return nullptr;
}

CSSIdentifierValue* ConsumeFontDisplay(CSSParserTokenRange& range) {
  return css_parsing_utils::ConsumeIdent<
      CSSValueID::kAuto, CSSValueID::kBlock, CSSValueID::kSwap,
      CSSValueID::kFallback, CSSValueID::kOptional>(range);
}

CSSValueList* ConsumeFontFaceUnicodeRange(CSSParserTokenRange& range) {
  CSSValueList* values = CSSValueList::CreateCommaSeparated();

  do {
    const CSSParserToken& token = range.ConsumeIncludingWhitespace();
    if (token.GetType() != kUnicodeRangeToken)
      return nullptr;

    UChar32 start = token.UnicodeRangeStart();
    UChar32 end = token.UnicodeRangeEnd();
    if (start > end)
      return nullptr;
    values->Append(
        *MakeGarbageCollected<cssvalue::CSSUnicodeRangeValue>(start, end));
  } while (css_parsing_utils::ConsumeCommaIncludingWhitespace(range));

  return values;
}

CSSValue* ConsumeFontFaceSrcURI(CSSParserTokenRange& range,
                                const CSSParserContext& context) {
  String url =
      css_parsing_utils::ConsumeUrlAsStringView(range, context).ToString();
  if (url.IsNull())
    return nullptr;
  CSSFontFaceSrcValue* uri_value(CSSFontFaceSrcValue::Create(
      url, context.CompleteURL(url), context.GetReferrer(),
      context.JavascriptWorld(),
      context.IsOriginClean() ? OriginClean::kTrue : OriginClean::kFalse,
      context.IsAdRelated()));

  if (range.Peek().FunctionId() != CSSValueID::kFormat)
    return uri_value;

  // FIXME: https://drafts.csswg.org/css-fonts says that format() contains a
  // comma-separated list of strings, but CSSFontFaceSrcValue stores only one
  // format. Allowing one format for now.
  CSSParserTokenRange args = css_parsing_utils::ConsumeFunction(range);
  const CSSParserToken& arg = args.ConsumeIncludingWhitespace();
  if ((arg.GetType() != kStringToken) || !args.AtEnd())
    return nullptr;
  uri_value->SetFormat(arg.Value().ToString());
  return uri_value;
}

CSSValue* ConsumeFontFaceSrcLocal(CSSParserTokenRange& range,
                                  const CSSParserContext& context) {
  CSSParserTokenRange args = css_parsing_utils::ConsumeFunction(range);
  if (args.Peek().GetType() == kStringToken) {
    const CSSParserToken& arg = args.ConsumeIncludingWhitespace();
    if (!args.AtEnd())
      return nullptr;
    return CSSFontFaceSrcValue::CreateLocal(
        arg.Value().ToString(), context.JavascriptWorld(),
        context.IsOriginClean() ? OriginClean::kTrue : OriginClean::kFalse,
        context.IsAdRelated());
  }
  if (args.Peek().GetType() == kIdentToken) {
    String family_name = css_parsing_utils::ConcatenateFamilyName(args);
    if (!args.AtEnd())
      return nullptr;
    return CSSFontFaceSrcValue::CreateLocal(
        family_name, context.JavascriptWorld(),
        context.IsOriginClean() ? OriginClean::kTrue : OriginClean::kFalse,
        context.IsAdRelated());
  }
  return nullptr;
}

CSSValueList* ConsumeFontFaceSrc(CSSParserTokenRange& range,
                                 const CSSParserContext& context) {
  CSSValueList* values = CSSValueList::CreateCommaSeparated();

  range.ConsumeWhitespace();
  do {
    const CSSParserToken& token = range.Peek();
    CSSValue* parsed_value = nullptr;
    if (token.FunctionId() == CSSValueID::kLocal)
      parsed_value = ConsumeFontFaceSrcLocal(range, context);
    else
      parsed_value = ConsumeFontFaceSrcURI(range, context);
    if (!parsed_value)
      return nullptr;
    values->Append(*parsed_value);
  } while (css_parsing_utils::ConsumeCommaIncludingWhitespace(range));
  return values;
}

CSSValue* ConsumeScrollTimelineSource(CSSParserTokenRange& range) {
  if (auto* selector_function =
          css_parsing_utils::ConsumeSelectorFunction(range)) {
    return selector_function;
  }
  return css_parsing_utils::ConsumeIdent<CSSValueID::kAuto, CSSValueID::kNone>(
      range);
}

CSSValue* ConsumeScrollTimelineOrientation(CSSParserTokenRange& range) {
  return css_parsing_utils::ConsumeIdent<
      CSSValueID::kAuto, CSSValueID::kBlock, CSSValueID::kInline,
      CSSValueID::kHorizontal, CSSValueID::kVertical>(range);
}

CSSValue* ConsumeTimeRange(CSSParserTokenRange& range,
                           const CSSParserContext& context) {
  if (auto* value = css_parsing_utils::ConsumeIdent<CSSValueID::kAuto>(range))
    return value;
  return css_parsing_utils::ConsumeTime(range, context, kValueRangeAll);
}

CSSValue* ConsumeDescriptor(StyleRule::RuleType rule_type,
                            AtRuleDescriptorID id,
                            const CSSTokenizedValue& tokenized_value,
                            const CSSParserContext& context) {
  using Parser = AtRuleDescriptorParser;
  CSSParserTokenRange range = tokenized_value.range;

  switch (rule_type) {
    case StyleRule::kFontFace:
      return Parser::ParseFontFaceDescriptor(id, range, context);
    case StyleRule::kProperty:
      return Parser::ParseAtPropertyDescriptor(id, tokenized_value, context);
    case StyleRule::kCounterStyle:
      return Parser::ParseAtCounterStyleDescriptor(id, range, context);
    case StyleRule::kScrollTimeline:
      return Parser::ParseAtScrollTimelineDescriptor(id, range, context);
    case StyleRule::kCharset:
    case StyleRule::kContainer:
    case StyleRule::kStyle:
    case StyleRule::kImport:
    case StyleRule::kMedia:
    case StyleRule::kPage:
    case StyleRule::kKeyframes:
    case StyleRule::kKeyframe:
    case StyleRule::kNamespace:
    case StyleRule::kSupports:
    case StyleRule::kViewport:
      // TODO(andruud): Handle other descriptor types here.
      NOTREACHED();
      return nullptr;
  }
}

CSSValue* ConsumeFontMetricOverride(CSSParserTokenRange& range,
                                    const CSSParserContext& context) {
  if (!RuntimeEnabledFeatures::CSSFontMetricsOverrideEnabled())
    return nullptr;
  if (CSSIdentifierValue* normal =
          css_parsing_utils::ConsumeIdent<CSSValueID::kNormal>(range)) {
    return normal;
  }
  return css_parsing_utils::ConsumePercent(range, context,
                                           kValueRangeNonNegative);
}

CSSValue* ConsumeAdvanceOverride(CSSParserTokenRange& range,
                                 const CSSParserContext& context) {
  if (!RuntimeEnabledFeatures::CSSFontFaceAdvanceOverrideEnabled())
    return nullptr;
  if (CSSIdentifierValue* normal =
          css_parsing_utils::ConsumeIdent<CSSValueID::kNormal>(range)) {
    return normal;
  }
  CSSValue* override_horizontal =
      css_parsing_utils::ConsumePercent(range, context, kValueRangeNonNegative);
  if (!override_horizontal)
    return nullptr;
  CSSValue* override_vertical_upright =
      css_parsing_utils::ConsumePercent(range, context, kValueRangeNonNegative);
  if (!override_vertical_upright)
    override_vertical_upright = override_horizontal;
  return MakeGarbageCollected<CSSValuePair>(override_horizontal,
                                            override_vertical_upright,
                                            CSSValuePair::kDropIdenticalValues);
}

}  // namespace

CSSValue* AtRuleDescriptorParser::ParseFontFaceDescriptor(
    AtRuleDescriptorID id,
    CSSParserTokenRange& range,
    const CSSParserContext& context) {
  CSSValue* parsed_value = nullptr;
  range.ConsumeWhitespace();
  switch (id) {
    case AtRuleDescriptorID::FontFamily:
      if (css_parsing_utils::ConsumeGenericFamily(range))
        return nullptr;
      parsed_value = css_parsing_utils::ConsumeFamilyName(range);
      break;
    case AtRuleDescriptorID::Src:  // This is a list of urls or local
                                   // references.
      parsed_value = ConsumeFontFaceSrc(range, context);
      break;
    case AtRuleDescriptorID::UnicodeRange:
      parsed_value = ConsumeFontFaceUnicodeRange(range);
      break;
    case AtRuleDescriptorID::FontDisplay:
      parsed_value = ConsumeFontDisplay(range);
      break;
    case AtRuleDescriptorID::FontStretch: {
      CSSParserContext::ParserModeOverridingScope scope(context,
                                                        kCSSFontFaceRuleMode);
      parsed_value = css_parsing_utils::ConsumeFontStretch(range, context);
      break;
    }
    case AtRuleDescriptorID::FontStyle: {
      CSSParserContext::ParserModeOverridingScope scope(context,
                                                        kCSSFontFaceRuleMode);
      parsed_value = css_parsing_utils::ConsumeFontStyle(range, context);
      break;
    }
    case AtRuleDescriptorID::FontVariant:
      parsed_value = ConsumeFontVariantList(range);
      break;
    case AtRuleDescriptorID::FontWeight: {
      CSSParserContext::ParserModeOverridingScope scope(context,
                                                        kCSSFontFaceRuleMode);
      parsed_value = css_parsing_utils::ConsumeFontWeight(range, context);
      break;
    }
    case AtRuleDescriptorID::FontFeatureSettings:
      parsed_value =
          css_parsing_utils::ConsumeFontFeatureSettings(range, context);
      break;
    case AtRuleDescriptorID::AscentOverride:
    case AtRuleDescriptorID::DescentOverride:
    case AtRuleDescriptorID::LineGapOverride:
      parsed_value = ConsumeFontMetricOverride(range, context);
      break;
    case AtRuleDescriptorID::AdvanceOverride:
      parsed_value = ConsumeAdvanceOverride(range, context);
      break;
    default:
      break;
  }

  if (!parsed_value || !range.AtEnd())
    return nullptr;

  return parsed_value;
}

CSSValue* AtRuleDescriptorParser::ParseFontFaceDescriptor(
    AtRuleDescriptorID id,
    const String& string,
    const CSSParserContext& context) {
  CSSTokenizer tokenizer(string);
  Vector<CSSParserToken, 32> tokens = tokenizer.TokenizeToEOF();
  CSSParserTokenRange range = CSSParserTokenRange(tokens);
  return ParseFontFaceDescriptor(id, range, context);
}

CSSValue* AtRuleDescriptorParser::ParseFontFaceDeclaration(
    CSSParserTokenRange& range,
    const CSSParserContext& context) {
  DCHECK_EQ(range.Peek().GetType(), kIdentToken);
  const CSSParserToken& token = range.ConsumeIncludingWhitespace();
  AtRuleDescriptorID id = token.ParseAsAtRuleDescriptorID();

  if (range.Consume().GetType() != kColonToken)
    return nullptr;  // Parse error

  return ParseFontFaceDescriptor(id, range, context);
}

CSSValue* AtRuleDescriptorParser::ParseAtPropertyDescriptor(
    AtRuleDescriptorID id,
    const CSSTokenizedValue& tokenized_value,
    const CSSParserContext& context) {
  CSSValue* parsed_value = nullptr;
  CSSParserTokenRange range = tokenized_value.range;
  switch (id) {
    case AtRuleDescriptorID::Syntax:
      range.ConsumeWhitespace();
      parsed_value = css_parsing_utils::ConsumeString(range);
      break;
    case AtRuleDescriptorID::InitialValue: {
      // Note that we must retain leading whitespace here.
      return CSSVariableParser::ParseDeclarationValue(
          g_null_atom, tokenized_value, false /* is_animation_tainted */,
          context);
    }
    case AtRuleDescriptorID::Inherits:
      range.ConsumeWhitespace();
      parsed_value = css_parsing_utils::ConsumeIdent<CSSValueID::kTrue,
                                                     CSSValueID::kFalse>(range);
      break;
    default:
      break;
  }

  if (!parsed_value || !range.AtEnd())
    return nullptr;

  return parsed_value;
}

CSSValue* AtRuleDescriptorParser::ParseAtScrollTimelineDescriptor(
    AtRuleDescriptorID id,
    CSSParserTokenRange& range,
    const CSSParserContext& context) {
  CSSValue* parsed_value = nullptr;

  range.ConsumeWhitespace();

  switch (id) {
    case AtRuleDescriptorID::Source:
      parsed_value = ConsumeScrollTimelineSource(range);
      break;
    case AtRuleDescriptorID::Orientation:
      parsed_value = ConsumeScrollTimelineOrientation(range);
      break;
    case AtRuleDescriptorID::Start:
    case AtRuleDescriptorID::End:
      parsed_value = css_parsing_utils::ConsumeScrollOffset(range, context);
      break;
    case AtRuleDescriptorID::TimeRange:
      parsed_value = ConsumeTimeRange(range, context);
      break;
    default:
      break;
  }

  if (!parsed_value || !range.AtEnd())
    return nullptr;

  return parsed_value;
}

bool AtRuleDescriptorParser::ParseAtRule(
    StyleRule::RuleType rule_type,
    AtRuleDescriptorID id,
    const CSSTokenizedValue& tokenized_value,
    const CSSParserContext& context,
    HeapVector<CSSPropertyValue, 256>& parsed_descriptors) {
  CSSValue* result = ConsumeDescriptor(rule_type, id, tokenized_value, context);

  if (!result)
    return false;
  // Convert to CSSPropertyID for legacy compatibility,
  // TODO(crbug.com/752745): Refactor CSSParserImpl to avoid using
  // the CSSPropertyID.
  CSSPropertyID equivalent_property_id = AtRuleDescriptorIDAsCSSPropertyID(id);
  parsed_descriptors.push_back(
      CSSPropertyValue(CSSPropertyName(equivalent_property_id), *result));
  return true;
}

}  // namespace blink
