// Copyright 2014 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/media_query_parser.h"

#include "third_party/blink/renderer/core/css/parser/css_parser_context.h"
#include "third_party/blink/renderer/core/css/parser/css_tokenizer.h"
#include "third_party/blink/renderer/core/media_type_names.h"

namespace blink {

scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySet(
    const String& query_string,
    const ExecutionContext* execution_context) {
  return ParseMediaQuerySet(
      CSSParserTokenRange(CSSTokenizer(query_string).TokenizeToEOF()),
      execution_context);
}

scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySet(
    CSSParserTokenRange range,
    const ExecutionContext* execution_context) {
  return MediaQueryParser(kMediaQuerySetParser, kHTMLStandardMode,
                          execution_context)
      .ParseImpl(range);
}

scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaQuerySetInMode(
    CSSParserTokenRange range,
    CSSParserMode mode,
    const ExecutionContext* execution_context) {
  return MediaQueryParser(kMediaQuerySetParser, mode, execution_context)
      .ParseImpl(range);
}

scoped_refptr<MediaQuerySet> MediaQueryParser::ParseMediaCondition(
    CSSParserTokenRange range,
    const ExecutionContext* execution_context) {
  return MediaQueryParser(kMediaConditionParser, kHTMLStandardMode,
                          execution_context)
      .ParseImpl(range);
}

const MediaQueryParser::State MediaQueryParser::kReadRestrictor =
    &MediaQueryParser::ReadRestrictor;
const MediaQueryParser::State MediaQueryParser::kReadMediaNot =
    &MediaQueryParser::ReadMediaNot;
const MediaQueryParser::State MediaQueryParser::kReadMediaType =
    &MediaQueryParser::ReadMediaType;
const MediaQueryParser::State MediaQueryParser::kReadAnd =
    &MediaQueryParser::ReadAnd;
const MediaQueryParser::State MediaQueryParser::kReadFeatureStart =
    &MediaQueryParser::ReadFeatureStart;
const MediaQueryParser::State MediaQueryParser::kReadFeature =
    &MediaQueryParser::ReadFeature;
const MediaQueryParser::State MediaQueryParser::kReadFeatureColon =
    &MediaQueryParser::ReadFeatureColon;
const MediaQueryParser::State MediaQueryParser::kReadFeatureValue =
    &MediaQueryParser::ReadFeatureValue;
const MediaQueryParser::State MediaQueryParser::kReadFeatureEnd =
    &MediaQueryParser::ReadFeatureEnd;
const MediaQueryParser::State MediaQueryParser::kSkipUntilComma =
    &MediaQueryParser::SkipUntilComma;
const MediaQueryParser::State MediaQueryParser::kSkipUntilBlockEnd =
    &MediaQueryParser::SkipUntilBlockEnd;
const MediaQueryParser::State MediaQueryParser::kDone = &MediaQueryParser::Done;

MediaQueryParser::MediaQueryParser(ParserType parser_type,
                                   CSSParserMode mode,
                                   const ExecutionContext* execution_context)
    : parser_type_(parser_type),
      query_set_(MediaQuerySet::Create()),
      mode_(mode),
      execution_context_(execution_context) {
  if (parser_type == kMediaQuerySetParser)
    state_ = &MediaQueryParser::ReadRestrictor;
  else  // MediaConditionParser
    state_ = &MediaQueryParser::ReadMediaNot;
}

MediaQueryParser::~MediaQueryParser() = default;

void MediaQueryParser::SetStateAndRestrict(
    State state,
    MediaQuery::RestrictorType restrictor) {
  media_query_data_.SetRestrictor(restrictor);
  state_ = state;
}

// State machine member functions start here
void MediaQueryParser::ReadRestrictor(CSSParserTokenType type,
                                      const CSSParserToken& token,
                                      CSSParserTokenRange& range) {
  ReadMediaType(type, token, range);
}

void MediaQueryParser::ReadMediaNot(CSSParserTokenType type,
                                    const CSSParserToken& token,
                                    CSSParserTokenRange& range) {
  if (type == kIdentToken && EqualIgnoringASCIICase(token.Value(), "not"))
    SetStateAndRestrict(kReadFeatureStart, MediaQuery::kNot);
  else
    ReadFeatureStart(type, token, range);
}

static bool IsRestrictorOrLogicalOperator(const CSSParserToken& token) {
  // FIXME: it would be more efficient to use lower-case always for tokenValue.
  return EqualIgnoringASCIICase(token.Value(), "not") ||
         EqualIgnoringASCIICase(token.Value(), "and") ||
         EqualIgnoringASCIICase(token.Value(), "or") ||
         EqualIgnoringASCIICase(token.Value(), "only");
}

void MediaQueryParser::ReadMediaType(CSSParserTokenType type,
                                     const CSSParserToken& token,
                                     CSSParserTokenRange& range) {
  if (type == kLeftParenthesisToken) {
    if (media_query_data_.Restrictor() != MediaQuery::kNone)
      state_ = kSkipUntilComma;
    else
      state_ = kReadFeature;
  } else if (type == kIdentToken) {
    if (state_ == kReadRestrictor &&
        EqualIgnoringASCIICase(token.Value(), "not")) {
      SetStateAndRestrict(kReadMediaType, MediaQuery::kNot);
    } else if (state_ == kReadRestrictor &&
               EqualIgnoringASCIICase(token.Value(), "only")) {
      SetStateAndRestrict(kReadMediaType, MediaQuery::kOnly);
    } else if (media_query_data_.Restrictor() != MediaQuery::kNone &&
               IsRestrictorOrLogicalOperator(token)) {
      state_ = kSkipUntilComma;
    } else {
      media_query_data_.SetMediaType(token.Value().ToString());
      state_ = kReadAnd;
    }
  } else if (type == kEOFToken &&
             (!query_set_->QueryVector().size() || state_ != kReadRestrictor)) {
    state_ = kDone;
  } else {
    state_ = kSkipUntilComma;
    if (type == kCommaToken)
      SkipUntilComma(type, token, range);
  }
}

void MediaQueryParser::ReadAnd(CSSParserTokenType type,
                               const CSSParserToken& token,
                               CSSParserTokenRange& range) {
  if (type == kIdentToken && EqualIgnoringASCIICase(token.Value(), "and")) {
    state_ = kReadFeatureStart;
  } else if (type == kCommaToken && parser_type_ != kMediaConditionParser) {
    query_set_->AddMediaQuery(media_query_data_.TakeMediaQuery());
    state_ = kReadRestrictor;
  } else if (type == kEOFToken) {
    state_ = kDone;
  } else {
    state_ = kSkipUntilComma;
  }
}

void MediaQueryParser::ReadFeatureStart(CSSParserTokenType type,
                                        const CSSParserToken& token,
                                        CSSParserTokenRange& range) {
  if (type == kLeftParenthesisToken)
    state_ = kReadFeature;
  else
    state_ = kSkipUntilComma;
}

void MediaQueryParser::ReadFeature(CSSParserTokenType type,
                                   const CSSParserToken& token,
                                   CSSParserTokenRange& range) {
  if (type == kIdentToken) {
    String media_feature = token.Value().ToString();
    if (IsMediaFeatureAllowedInMode(media_feature)) {
      media_query_data_.SetMediaFeature(media_feature);
      state_ = kReadFeatureColon;
    } else {
      state_ = kSkipUntilComma;
    }
  } else {
    state_ = kSkipUntilComma;
  }
}

void MediaQueryParser::ReadFeatureColon(CSSParserTokenType type,
                                        const CSSParserToken& token,
                                        CSSParserTokenRange& range) {
  if (type == kColonToken) {
    while (range.Peek().GetType() == kWhitespaceToken)
      range.Consume();
    if (range.Peek().GetType() == kRightParenthesisToken || type == kEOFToken)
      state_ = kSkipUntilBlockEnd;
    else
      state_ = kReadFeatureValue;
  } else if (type == kRightParenthesisToken || type == kEOFToken) {
    media_query_data_.AddExpression(range, execution_context_);
    ReadFeatureEnd(type, token, range);
  } else {
    state_ = kSkipUntilBlockEnd;
  }
}

void MediaQueryParser::ReadFeatureValue(CSSParserTokenType type,
                                        const CSSParserToken& token,
                                        CSSParserTokenRange& range) {
  if (type == kDimensionToken &&
      token.GetUnitType() == CSSPrimitiveValue::UnitType::kUnknown) {
    range.Consume();
    state_ = kSkipUntilComma;
  } else {
    media_query_data_.AddExpression(range, execution_context_);
    state_ = kReadFeatureEnd;
  }
}

void MediaQueryParser::ReadFeatureEnd(CSSParserTokenType type,
                                      const CSSParserToken& token,
                                      CSSParserTokenRange& range) {
  if (type == kRightParenthesisToken || type == kEOFToken) {
    if (media_query_data_.LastExpressionValid())
      state_ = kReadAnd;
    else
      state_ = kSkipUntilComma;
  } else {
    media_query_data_.RemoveLastExpression();
    state_ = kSkipUntilBlockEnd;
  }
}

void MediaQueryParser::SkipUntilComma(CSSParserTokenType type,
                                      const CSSParserToken& token,
                                      CSSParserTokenRange& range) {
  if ((type == kCommaToken && !block_watcher_.BlockLevel()) ||
      type == kEOFToken) {
    state_ = kReadRestrictor;
    media_query_data_.Clear();
    query_set_->AddMediaQuery(MediaQuery::CreateNotAll());
  }
}

void MediaQueryParser::SkipUntilBlockEnd(CSSParserTokenType type,
                                         const CSSParserToken& token,
                                         CSSParserTokenRange& range) {
  if (token.GetBlockType() == CSSParserToken::kBlockEnd &&
      !block_watcher_.BlockLevel())
    state_ = kSkipUntilComma;
}

void MediaQueryParser::Done(CSSParserTokenType type,
                            const CSSParserToken& token,
                            CSSParserTokenRange& range) {}

void MediaQueryParser::HandleBlocks(const CSSParserToken& token) {
  if (token.GetBlockType() == CSSParserToken::kBlockStart &&
      (token.GetType() != kLeftParenthesisToken || block_watcher_.BlockLevel()))
    state_ = kSkipUntilBlockEnd;
}

void MediaQueryParser::ProcessToken(const CSSParserToken& token,
                                    CSSParserTokenRange& range) {
  CSSParserTokenType type = token.GetType();

  if (state_ != kReadFeatureValue || type == kWhitespaceToken) {
    HandleBlocks(token);
    block_watcher_.HandleToken(token);
    range.Consume();
  }

  // Call the function that handles current state
  if (type != kWhitespaceToken)
    ((this)->*(state_))(type, token, range);
}

// The state machine loop
scoped_refptr<MediaQuerySet> MediaQueryParser::ParseImpl(
    CSSParserTokenRange range) {
  while (!range.AtEnd())
    ProcessToken(range.Peek(), range);

  // FIXME: Can we get rid of this special case?
  if (parser_type_ == kMediaQuerySetParser)
    ProcessToken(CSSParserToken(kEOFToken), range);

  if (state_ != kReadAnd && state_ != kReadRestrictor && state_ != kDone &&
      state_ != kReadMediaNot)
    query_set_->AddMediaQuery(MediaQuery::CreateNotAll());
  else if (media_query_data_.CurrentMediaQueryChanged())
    query_set_->AddMediaQuery(media_query_data_.TakeMediaQuery());

  return query_set_;
}

bool MediaQueryParser::IsMediaFeatureAllowedInMode(
    const String& media_feature) const {
  return mode_ == kUASheetMode ||
         media_feature != media_feature_names::kImmersiveMediaFeature;
}

MediaQueryData::MediaQueryData()
    : restrictor_(MediaQuery::kNone),
      media_type_(media_type_names::kAll),
      media_type_set_(false),
      fake_context_(*MakeGarbageCollected<CSSParserContext>(
          kHTMLStandardMode,
          SecureContextMode::kInsecureContext)) {}

void MediaQueryData::Clear() {
  restrictor_ = MediaQuery::kNone;
  media_type_ = media_type_names::kAll;
  media_type_set_ = false;
  media_feature_ = String();
  expressions_.clear();
}

std::unique_ptr<MediaQuery> MediaQueryData::TakeMediaQuery() {
  std::unique_ptr<MediaQuery> media_query = std::make_unique<MediaQuery>(
      restrictor_, std::move(media_type_), std::move(expressions_));
  Clear();
  return media_query;
}

void MediaQueryData::AddExpression(CSSParserTokenRange& range,
                                   const ExecutionContext* execution_context) {
  expressions_.push_back(MediaQueryExp::Create(
      media_feature_, range, fake_context_, execution_context));
}

bool MediaQueryData::LastExpressionValid() {
  return expressions_.back().IsValid();
}

void MediaQueryData::RemoveLastExpression() {
  expressions_.pop_back();
}

void MediaQueryData::SetMediaType(const String& media_type) {
  media_type_ = media_type;
  media_type_set_ = true;
}

}  // namespace blink
