use crate::declaration::{parse_declaration, DeclarationBlock, DeclarationList};
use crate::error::{Error, ParserError, PrinterError};
use crate::media_query::*;
use crate::printer::Printer;
use crate::properties::custom::TokenList;
use crate::rules::container::{ContainerCondition, ContainerName, ContainerRule};
use crate::rules::font_feature_values::FontFeatureValuesRule;
use crate::rules::font_palette_values::FontPaletteValuesRule;
use crate::rules::layer::{LayerBlockRule, LayerStatementRule};
use crate::rules::nesting::NestedDeclarationsRule;
use crate::rules::property::PropertyRule;
use crate::rules::scope::ScopeRule;
use crate::rules::starting_style::StartingStyleRule;
use crate::rules::view_transition::ViewTransitionRule;
use crate::rules::viewport::ViewportRule;

use crate::properties::font::FamilyName;
use crate::rules::{
  counter_style::CounterStyleRule,
  custom_media::CustomMediaRule,
  document::MozDocumentRule,
  font_face::{FontFaceDeclarationParser, FontFaceRule},
  import::ImportRule,
  keyframes::{KeyframeListParser, KeyframesName, KeyframesRule},
  layer::LayerName,
  media::MediaRule,
  namespace::NamespaceRule,
  nesting::NestingRule,
  page::{PageRule, PageSelector},
  style::StyleRule,
  supports::{SupportsCondition, SupportsRule},
  unknown::UnknownAtRule,
  CssRule, CssRuleList, Location,
};
use crate::selector::{SelectorList, SelectorParser};
use crate::traits::{Parse, ParseWithOptions};
use crate::values::ident::{CustomIdent, DashedIdent};
use crate::values::string::CowArcStr;
use crate::vendor_prefix::VendorPrefix;
#[cfg(feature = "visitor")]
use crate::visitor::{Visit, VisitTypes, Visitor};
use bitflags::bitflags;
use cssparser::*;
use parcel_selectors::parser::{NestingRequirement, ParseErrorRecovery};
use std::sync::{Arc, RwLock};

bitflags! {
  /// Parser feature flags to enable.
  #[derive(Clone, Debug, Default)]
  pub struct ParserFlags: u8 {
    /// Whether the enable the [CSS nesting](https://www.w3.org/TR/css-nesting-1/) draft syntax.
    const NESTING = 1 << 0;
    /// Whether to enable the [custom media](https://drafts.csswg.org/mediaqueries-5/#custom-mq) draft syntax.
    const CUSTOM_MEDIA = 1 << 1;
    /// Whether to enable the non-standard >>> and /deep/ selector combinators used by Vue and Angular.
    const DEEP_SELECTOR_COMBINATOR = 1 << 2;
  }
}

/// CSS parsing options.
#[derive(Clone, Debug, Default)]
pub struct ParserOptions<'o, 'i> {
  /// Filename to use in error messages.
  pub filename: String,
  /// Whether the enable [CSS modules](https://github.com/css-modules/css-modules).
  pub css_modules: Option<crate::css_modules::Config<'o>>,
  /// The source index to assign to all parsed rules. Impacts the source map when
  /// the style sheet is serialized.
  pub source_index: u32,
  /// Whether to ignore invalid rules and declarations rather than erroring.
  pub error_recovery: bool,
  /// A list that will be appended to when a warning occurs.
  pub warnings: Option<Arc<RwLock<Vec<Error<ParserError<'i>>>>>>,
  /// Feature flags to enable.
  pub flags: ParserFlags,
}

impl<'o, 'i> ParserOptions<'o, 'i> {
  #[inline]
  pub(crate) fn warn(&self, warning: ParseError<'i, ParserError<'i>>) {
    if let Some(warnings) = &self.warnings {
      if let Ok(mut warnings) = warnings.write() {
        warnings.push(Error::from(warning, self.filename.clone()));
      }
    }
  }
}

#[derive(Clone, Default)]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
pub struct DefaultAtRuleParser;
impl<'i> crate::traits::AtRuleParser<'i> for DefaultAtRuleParser {
  type AtRule = DefaultAtRule;
  type Error = ();
  type Prelude = ();
}

#[derive(PartialEq, Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
pub struct DefaultAtRule;
impl crate::traits::ToCss for DefaultAtRule {
  fn to_css<W: std::fmt::Write>(&self, _: &mut Printer<W>) -> Result<(), PrinterError> {
    Err(PrinterError {
      kind: crate::error::PrinterErrorKind::FmtError,
      loc: None,
    })
  }
}

#[cfg(feature = "into_owned")]
impl<'any> static_self::IntoOwned<'any> for DefaultAtRule {
  type Owned = Self;
  fn into_owned(self) -> Self {
    self
  }
}

#[cfg(feature = "visitor")]
#[cfg_attr(docsrs, doc(cfg(feature = "visitor")))]
impl<'i, V: Visitor<'i, DefaultAtRule>> Visit<'i, DefaultAtRule, V> for DefaultAtRule {
  const CHILD_TYPES: VisitTypes = VisitTypes::empty();
  fn visit_children(&mut self, _: &mut V) -> Result<(), V::Error> {
    Ok(())
  }
}

#[derive(PartialEq, PartialOrd)]
enum State {
  Start = 1,
  Layers = 2,
  Imports = 3,
  Namespaces = 4,
  Body = 5,
}

/// The parser for the top-level rules in a stylesheet.
pub struct TopLevelRuleParser<'a, 'o, 'i, T: crate::traits::AtRuleParser<'i>> {
  pub options: &'a ParserOptions<'o, 'i>,
  state: State,
  at_rule_parser: &'a mut T,
  rules: &'a mut CssRuleList<'i, T::AtRule>,
}

impl<'a, 'o, 'b, 'i, T: crate::traits::AtRuleParser<'i>> TopLevelRuleParser<'a, 'o, 'i, T> {
  pub fn new(
    options: &'a ParserOptions<'o, 'i>,
    at_rule_parser: &'a mut T,
    rules: &'a mut CssRuleList<'i, T::AtRule>,
  ) -> Self {
    TopLevelRuleParser {
      options,
      state: State::Start,
      at_rule_parser,
      rules,
    }
  }

  pub fn nested<'x: 'b>(&'x mut self) -> NestedRuleParser<'x, 'o, 'i, T> {
    NestedRuleParser {
      options: &self.options,
      at_rule_parser: self.at_rule_parser,
      declarations: DeclarationList::new(),
      important_declarations: DeclarationList::new(),
      rules: &mut self.rules,
      is_in_style_rule: false,
      allow_declarations: false,
    }
  }
}

/// A rule prelude for at-rule with block.
#[derive(Debug)]
#[allow(dead_code)]
pub enum AtRulePrelude<'i, T> {
  /// A @font-face rule prelude.
  FontFace,
  /// A @font-feature-values rule prelude, with its FamilyName list.
  FontFeatureValues(Vec<FamilyName<'i>>),
  /// A @font-palette-values rule prelude, with its name.
  FontPaletteValues(DashedIdent<'i>),
  /// A @counter-style rule prelude, with its counter style name.
  CounterStyle(CustomIdent<'i>),
  /// A @media rule prelude, with its media queries.
  Media(MediaList<'i>),
  /// A @custom-media rule prelude.
  CustomMedia(DashedIdent<'i>, MediaList<'i>),
  /// An @supports rule, with its conditional
  Supports(SupportsCondition<'i>),
  /// A @viewport rule prelude.
  Viewport(VendorPrefix),
  /// A @keyframes rule, with its animation name and vendor prefix if exists.
  Keyframes(KeyframesName<'i>, VendorPrefix),
  /// A @page rule prelude.
  Page(Vec<PageSelector<'i>>),
  /// A @-moz-document rule.
  MozDocument,
  /// A @import rule prelude.
  Import(
    CowRcStr<'i>,
    MediaList<'i>,
    Option<SupportsCondition<'i>>,
    Option<Option<LayerName<'i>>>,
  ),
  /// A @namespace rule prelude.
  Namespace(Option<CowRcStr<'i>>, CowRcStr<'i>),
  /// A @charset rule prelude.
  Charset,
  /// A @nest prelude.
  Nest(SelectorList<'i>),
  /// An @layer prelude.
  Layer(Vec<LayerName<'i>>),
  /// An @property prelude.
  Property(DashedIdent<'i>),
  /// A @container prelude.
  Container(Option<ContainerName<'i>>, ContainerCondition<'i>),
  /// A @starting-style prelude.
  StartingStyle,
  /// A @scope rule prelude.
  Scope(Option<SelectorList<'i>>, Option<SelectorList<'i>>),
  /// A @view-transition rule prelude.
  ViewTransition,
  /// An unknown prelude.
  Unknown(CowArcStr<'i>, TokenList<'i>),
  /// A custom prelude.
  Custom(T),
}

impl<'i, T> AtRulePrelude<'i, T> {
  // https://drafts.csswg.org/css-nesting/#conditionals
  //     In addition to nested style rules, this specification allows nested group rules inside
  //     of style rules: any at-rule whose body contains style rules can be nested inside of a
  //     style rule as well.
  fn allowed_in_style_rule(&self) -> bool {
    match *self {
      Self::Media(..)
      | Self::Supports(..)
      | Self::Container(..)
      | Self::MozDocument
      | Self::Layer(..)
      | Self::StartingStyle
      | Self::Scope(..)
      | Self::Nest(..)
      | Self::Unknown(..)
      | Self::Custom(..) => true,

      Self::Namespace(..)
      | Self::FontFace
      | Self::FontFeatureValues(..)
      | Self::FontPaletteValues(..)
      | Self::CounterStyle(..)
      | Self::Keyframes(..)
      | Self::Page(..)
      | Self::Property(..)
      | Self::Import(..)
      | Self::CustomMedia(..)
      | Self::Viewport(..)
      | Self::Charset
      | Self::ViewTransition => false,
    }
  }
}

impl<'a, 'o, 'i, T: crate::traits::AtRuleParser<'i>> AtRuleParser<'i> for TopLevelRuleParser<'a, 'o, 'i, T> {
  type Prelude = AtRulePrelude<'i, T::Prelude>;
  type AtRule = ();
  type Error = ParserError<'i>;

  fn parse_prelude<'t>(
    &mut self,
    name: CowRcStr<'i>,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::Prelude, ParseError<'i, Self::Error>> {
    match_ignore_ascii_case! { &*name,
      "import" => {
        if self.state > State::Imports {
          return Err(input.new_custom_error(ParserError::UnexpectedImportRule))
        }

        let url_string = input.expect_url_or_string()?.clone();

        let layer = if input.try_parse(|input| input.expect_ident_matching("layer")).is_ok() {
          Some(None)
        } else if input.try_parse(|input| input.expect_function_matching("layer")).is_ok() {
          let name = input.parse_nested_block(LayerName::parse).map(|name| Some(name))?;
          Some(name)
        } else {
          None
        };

        let supports = if input.try_parse(|input| input.expect_function_matching("supports")).is_ok() {
          Some(input.parse_nested_block(|input| {
            input.try_parse(SupportsCondition::parse).or_else(|_| SupportsCondition::parse_declaration(input))
          })?)
        } else {
          None
        };
        let media = MediaList::parse(input, &self.options)?;
        return Ok(AtRulePrelude::Import(url_string, media, supports, layer));
      },
      "namespace" => {
        if self.state > State::Namespaces {
          return Err(input.new_custom_error(ParserError::UnexpectedNamespaceRule))
        }

        let prefix = input.try_parse(|input| input.expect_ident_cloned()).ok();
        let namespace = input.expect_url_or_string()?;
        let prelude = AtRulePrelude::Namespace(prefix, namespace);
        return Ok(prelude);
      },
      "charset" => {
        // @charset is removed by rust-cssparser if it’s the first rule in the stylesheet.
        // Anything left is technically invalid, however, users often concatenate CSS files
        // together, so we are more lenient and simply ignore @charset rules in the middle of a file.
        input.expect_string()?;
        return Ok(AtRulePrelude::Charset)
      },
      "custom-media" if self.options.flags.contains(ParserFlags::CUSTOM_MEDIA) => {
        let name = DashedIdent::parse(input)?;
        let media = MediaList::parse(input, &self.options)?;
        return Ok(AtRulePrelude::CustomMedia(name, media))
      },
      "property" => {
        let name = DashedIdent::parse(input)?;
        return Ok(AtRulePrelude::Property(name))
      },
      _ => {}
    }

    AtRuleParser::parse_prelude(&mut self.nested(), name, input)
  }

  #[inline]
  fn parse_block<'t>(
    &mut self,
    prelude: Self::Prelude,
    start: &ParserState,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::AtRule, ParseError<'i, Self::Error>> {
    self.state = State::Body;
    AtRuleParser::parse_block(&mut self.nested(), prelude, start, input)
  }

  #[inline]
  fn rule_without_block(
    &mut self,
    prelude: AtRulePrelude<'i, T::Prelude>,
    start: &ParserState,
  ) -> Result<Self::AtRule, ()> {
    let loc = start.source_location();
    let loc = Location {
      source_index: self.options.source_index,
      line: loc.line,
      column: loc.column,
    };

    match prelude {
      AtRulePrelude::Import(url, media, supports, layer) => {
        self.state = State::Imports;
        self.rules.0.push(CssRule::Import(ImportRule {
          url: url.into(),
          layer,
          supports,
          media,
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::Namespace(prefix, url) => {
        self.state = State::Namespaces;

        self.rules.0.push(CssRule::Namespace(NamespaceRule {
          prefix: prefix.map(|x| x.into()),
          url: url.into(),
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::CustomMedia(name, query) => {
        self.state = State::Body;
        self.rules.0.push(CssRule::CustomMedia(CustomMediaRule { name, query, loc }));
        Ok(())
      }
      AtRulePrelude::Layer(_) => {
        // @layer statements are allowed before @import rules, but cannot be interleaved.
        if self.state <= State::Layers {
          self.state = State::Layers;
        } else {
          self.state = State::Body;
        }
        AtRuleParser::rule_without_block(&mut self.nested(), prelude, start)
      }
      AtRulePrelude::Charset => Ok(()),
      AtRulePrelude::Unknown(name, prelude) => {
        self.rules.0.push(CssRule::Unknown(UnknownAtRule {
          name,
          prelude,
          block: None,
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::Custom(_) => {
        self.state = State::Body;
        AtRuleParser::rule_without_block(&mut self.nested(), prelude, start)
      }
      _ => Err(()),
    }
  }
}

impl<'a, 'o, 'i, T: crate::traits::AtRuleParser<'i>> QualifiedRuleParser<'i>
  for TopLevelRuleParser<'a, 'o, 'i, T>
{
  type Prelude = SelectorList<'i>;
  type QualifiedRule = ();
  type Error = ParserError<'i>;

  #[inline]
  fn parse_prelude<'t>(
    &mut self,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::Prelude, ParseError<'i, Self::Error>> {
    self.state = State::Body;
    QualifiedRuleParser::parse_prelude(&mut self.nested(), input)
  }

  #[inline]
  fn parse_block<'t>(
    &mut self,
    prelude: Self::Prelude,
    start: &ParserState,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::QualifiedRule, ParseError<'i, Self::Error>> {
    QualifiedRuleParser::parse_block(&mut self.nested(), prelude, start, input)
  }
}

pub struct NestedRuleParser<'a, 'o, 'i, T: crate::traits::AtRuleParser<'i>> {
  pub options: &'a ParserOptions<'o, 'i>,
  pub at_rule_parser: &'a mut T,
  declarations: DeclarationList<'i>,
  important_declarations: DeclarationList<'i>,
  rules: &'a mut CssRuleList<'i, T::AtRule>,
  is_in_style_rule: bool,
  allow_declarations: bool,
}

impl<'a, 'o, 'b, 'i, T: crate::traits::AtRuleParser<'i>> NestedRuleParser<'a, 'o, 'i, T> {
  pub fn parse_nested<'t>(
    &mut self,
    input: &mut Parser<'i, 't>,
    is_style_rule: bool,
  ) -> Result<(DeclarationBlock<'i>, CssRuleList<'i, T::AtRule>), ParseError<'i, ParserError<'i>>> {
    let mut rules = CssRuleList(vec![]);
    let mut nested_parser = NestedRuleParser {
      options: self.options,
      at_rule_parser: self.at_rule_parser,
      declarations: DeclarationList::new(),
      important_declarations: DeclarationList::new(),
      rules: &mut rules,
      is_in_style_rule: self.is_in_style_rule || is_style_rule,
      allow_declarations: self.allow_declarations || self.is_in_style_rule || is_style_rule,
    };

    let parse_declarations = nested_parser.parse_declarations();
    let mut errors = Vec::new();
    let mut iter = RuleBodyParser::new(input, &mut nested_parser);
    while let Some(result) = iter.next() {
      match result {
        Ok(()) => {}
        Err((e, _)) => {
          if parse_declarations {
            iter.parser.declarations.clear();
            iter.parser.important_declarations.clear();
            errors.push(e);
          } else {
            if iter.parser.options.error_recovery {
              iter.parser.options.warn(e);
              continue;
            }
            return Err(e);
          }
        }
      }
    }

    if parse_declarations {
      if !errors.is_empty() {
        if self.options.error_recovery {
          for err in errors {
            self.options.warn(err);
          }
        } else {
          return Err(errors.remove(0));
        }
      }
    }

    Ok((
      DeclarationBlock {
        declarations: nested_parser.declarations,
        important_declarations: nested_parser.important_declarations,
      },
      rules,
    ))
  }

  fn parse_style_block<'t>(
    &mut self,
    input: &mut Parser<'i, 't>,
  ) -> Result<CssRuleList<'i, T::AtRule>, ParseError<'i, ParserError<'i>>> {
    let loc = input.current_source_location();
    let loc = Location {
      source_index: self.options.source_index,
      line: loc.line,
      column: loc.column,
    };

    // Declarations can be immediately within @media and @supports blocks that are nested within a parent style rule.
    // These are wrapped in an (invisible) NestedDeclarationsRule.
    let (declarations, mut rules) = self.parse_nested(input, false)?;

    if declarations.len() > 0 {
      rules.0.insert(
        0,
        CssRule::NestedDeclarations(NestedDeclarationsRule { declarations, loc }),
      )
    }

    Ok(rules)
  }

  fn loc(&self, start: &ParserState) -> Location {
    let loc = start.source_location();
    Location {
      source_index: self.options.source_index,
      line: loc.line,
      column: loc.column,
    }
  }
}

impl<'a, 'o, 'b, 'i, T: crate::traits::AtRuleParser<'i>> AtRuleParser<'i> for NestedRuleParser<'a, 'o, 'i, T> {
  type Prelude = AtRulePrelude<'i, T::Prelude>;
  type AtRule = ();
  type Error = ParserError<'i>;

  fn parse_prelude<'t>(
    &mut self,
    name: CowRcStr<'i>,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::Prelude, ParseError<'i, Self::Error>> {
    let result = match_ignore_ascii_case! { &*name,
      "media" => {
        let media = MediaList::parse(input, &self.options)?;
        AtRulePrelude::Media(media)
      },
      "supports" => {
        let cond = SupportsCondition::parse(input, )?;
        AtRulePrelude::Supports(cond)
      },
      "font-face" => {
        AtRulePrelude::FontFace
      },
      // "font-feature-values" => {
      //     if !cfg!(feature = "gecko") {
      //         // Support for this rule is not fully implemented in Servo yet.
      //         return Err(input.new_custom_error(StyleParseErrorKind::UnsupportedAtRule(name.clone())))
      //     }
      //     let family_names = parse_family_name_list(self.context, input)?;
      //     Ok(AtRuleType::WithBlock(AtRuleBlockPrelude::FontFeatureValues(family_names)))
      // },
      "font-feature-values" => {
        let names = match Vec::<FamilyName>::parse(input) {
          Ok(names) => names,
          Err(e) => return Err(e)
        };

        AtRulePrelude::FontFeatureValues(names)
      },
      "font-palette-values" => {
        let name = DashedIdent::parse(input)?;
        AtRulePrelude::FontPaletteValues(name)
      },
      "counter-style" => {
        let name = CustomIdent::parse(input)?;
        AtRulePrelude::CounterStyle(name)
      },
      "viewport" | "-ms-viewport" => {
        let prefix = if starts_with_ignore_ascii_case(&*name, "-ms") {
          VendorPrefix::Ms
        } else {
          VendorPrefix::None
        };
        AtRulePrelude::Viewport(prefix)
      },
      "keyframes" | "-webkit-keyframes" | "-moz-keyframes" | "-o-keyframes" | "-ms-keyframes" => {
        let prefix = if starts_with_ignore_ascii_case(&*name, "-webkit-") {
          VendorPrefix::WebKit
        } else if starts_with_ignore_ascii_case(&*name, "-moz-") {
          VendorPrefix::Moz
        } else if starts_with_ignore_ascii_case(&*name, "-o-") {
          VendorPrefix::O
        } else if starts_with_ignore_ascii_case(&*name, "-ms-") {
          VendorPrefix::Ms
        } else {
          VendorPrefix::None
        };

        let name = input.try_parse(KeyframesName::parse)?;
        AtRulePrelude::Keyframes(name, prefix)
      },
      "page" => {
        let selectors = input.try_parse(|input| input.parse_comma_separated(PageSelector::parse)).unwrap_or_default();
        AtRulePrelude::Page(selectors)
      },
      "-moz-document" => {
        // Firefox only supports the url-prefix() function with no arguments as a legacy CSS hack.
        // See https://css-tricks.com/snippets/css/css-hacks-targeting-firefox/
        input.expect_function_matching("url-prefix")?;
        input.parse_nested_block(|input| {
          // Firefox also allows an empty string as an argument...
          // https://github.com/mozilla/gecko-dev/blob/0077f2248712a1b45bf02f0f866449f663538164/servo/components/style/stylesheets/document_rule.rs#L303
          let _ = input.try_parse(|input| -> Result<(), ParseError<'i, Self::Error>> {
            let s = input.expect_string()?;
            if !s.is_empty() {
              return Err(input.new_custom_error(ParserError::InvalidValue))
            }
            Ok(())
          });
          input.expect_exhausted()?;
          Ok(())
        })?;

        AtRulePrelude::MozDocument
      },
      "layer" => {
        let names = match Vec::<LayerName>::parse(input) {
          Ok(names) => names,
          Err(ParseError { kind: ParseErrorKind::Basic(BasicParseErrorKind::EndOfInput), .. }) => Vec::new(),
          Err(e) => return Err(e)
        };
        AtRulePrelude::Layer(names)
      },
      "container" => {
        let name = input.try_parse(ContainerName::parse).ok();
        let condition = ContainerCondition::parse_with_options(input, &self.options)?;
        AtRulePrelude::Container(name, condition)
      },
      "starting-style" => {
        AtRulePrelude::StartingStyle
      },
      "scope" => {
        let selector_parser = SelectorParser {
          is_nesting_allowed: true,
          options: &self.options,
        };

        let scope_start = if input.try_parse(|input| input.expect_parenthesis_block()).is_ok() {
          Some(input.parse_nested_block(|input| {
            // https://drafts.csswg.org/css-cascade-6/#scoped-rules
            // TODO: disallow pseudo elements?
            SelectorList::parse_relative(&selector_parser, input, ParseErrorRecovery::IgnoreInvalidSelector, NestingRequirement::None)
          })?)
        } else {
          None
        };

        let scope_end = if input.try_parse(|input| input.expect_ident_matching("to")).is_ok() {
          input.expect_parenthesis_block()?;
          Some(input.parse_nested_block(|input| {
            SelectorList::parse_relative(&selector_parser, input, ParseErrorRecovery::IgnoreInvalidSelector, NestingRequirement::None)
          })?)
        } else {
          None
        };

        AtRulePrelude::Scope(scope_start, scope_end)
      },
      "view-transition" => {
        AtRulePrelude::ViewTransition
      },
      "nest" if self.is_in_style_rule => {
        self.options.warn(input.new_custom_error(ParserError::DeprecatedNestRule));
        let selector_parser = SelectorParser {
          is_nesting_allowed: true,
          options: &self.options,
        };
        let selectors = SelectorList::parse(&selector_parser, input, ParseErrorRecovery::DiscardList, NestingRequirement::Contained)?;
        AtRulePrelude::Nest(selectors)
      },

      "value" if self.options.css_modules.is_some() => {
        return Err(input.new_custom_error(ParserError::DeprecatedCssModulesValueRule));
      },


      _ => parse_custom_at_rule_prelude(&name, input, self.options, self.at_rule_parser)?
    };

    if self.is_in_style_rule && !result.allowed_in_style_rule() {
      return Err(input.new_error(BasicParseErrorKind::AtRuleInvalid(name.clone())));
    }

    Ok(result)
  }

  #[inline]
  fn rule_without_block(
    &mut self,
    prelude: AtRulePrelude<'i, T::Prelude>,
    start: &ParserState,
  ) -> Result<Self::AtRule, ()> {
    let loc = self.loc(start);
    match prelude {
      AtRulePrelude::Layer(names) => {
        if self.is_in_style_rule || names.is_empty() {
          return Err(());
        }

        self.rules.0.push(CssRule::LayerStatement(LayerStatementRule { names, loc }));
        Ok(())
      }
      AtRulePrelude::Unknown(name, prelude) => {
        self.rules.0.push(CssRule::Unknown(UnknownAtRule {
          name,
          prelude,
          block: None,
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::Custom(prelude) => {
        self.rules.0.push(parse_custom_at_rule_without_block(
          prelude,
          start,
          self.options,
          self.at_rule_parser,
          self.is_in_style_rule,
        )?);
        Ok(())
      }
      _ => Err(()),
    }
  }

  fn parse_block<'t>(
    &mut self,
    prelude: Self::Prelude,
    start: &ParserState,
    input: &mut Parser<'i, 't>,
  ) -> Result<(), ParseError<'i, Self::Error>> {
    let loc = self.loc(start);
    match prelude {
      AtRulePrelude::FontFace => {
        let mut decl_parser = FontFaceDeclarationParser;
        let mut parser = RuleBodyParser::new(input, &mut decl_parser);
        let mut properties = vec![];
        while let Some(decl) = parser.next() {
          if let Ok(decl) = decl {
            properties.push(decl);
          }
        }
        self.rules.0.push(CssRule::FontFace(FontFaceRule { properties, loc }));
        Ok(())
      }
      // AtRuleBlockPrelude::FontFeatureValues(family_names) => {
      //     let context = ParserContext::new_with_rule_type(
      //         self.context,
      //         CssRuleType::FontFeatureValues,
      //         self.namespaces,
      //     );

      //     Ok(CssRule::FontFeatureValues(Arc::new(self.shared_lock.wrap(
      //         FontFeatureValuesRule::parse(
      //             &context,
      //             input,
      //             family_names,
      //             start.source_location(),
      //         ),
      //     ))))
      // },
      AtRulePrelude::FontPaletteValues(name) => {
        let rule = FontPaletteValuesRule::parse(name, input, loc)?;
        self.rules.0.push(CssRule::FontPaletteValues(rule));
        Ok(())
      }
      AtRulePrelude::CounterStyle(name) => {
        self.rules.0.push(CssRule::CounterStyle(CounterStyleRule {
          name,
          declarations: DeclarationBlock::parse(input, self.options)?,
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::Media(query) => {
        let rules = self.parse_style_block(input)?;
        self.rules.0.push(CssRule::Media(MediaRule { query, rules, loc }));
        Ok(())
      }
      AtRulePrelude::Supports(condition) => {
        let rules = self.parse_style_block(input)?;
        self.rules.0.push(CssRule::Supports(SupportsRule { condition, rules, loc }));
        Ok(())
      }
      AtRulePrelude::Container(name, condition) => {
        let rules = self.parse_style_block(input)?;
        self.rules.0.push(CssRule::Container(ContainerRule {
          name,
          condition,
          rules,
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::Scope(scope_start, scope_end) => {
        let rules = self.parse_style_block(input)?;
        self.rules.0.push(CssRule::Scope(ScopeRule {
          scope_start,
          scope_end,
          rules,
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::Viewport(vendor_prefix) => {
        self.rules.0.push(CssRule::Viewport(ViewportRule {
          vendor_prefix,
          // TODO: parse viewport descriptors rather than properties
          // https://drafts.csswg.org/css-device-adapt/#viewport-desc
          declarations: DeclarationBlock::parse(input, self.options)?,
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::Keyframes(name, vendor_prefix) => {
        let mut parser = KeyframeListParser;
        let iter = RuleBodyParser::new(input, &mut parser);
        self.rules.0.push(CssRule::Keyframes(KeyframesRule {
          name,
          keyframes: iter.filter_map(Result::ok).collect(),
          vendor_prefix,
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::Page(selectors) => {
        let rule = PageRule::parse(selectors, input, loc, self.options)?;
        self.rules.0.push(CssRule::Page(rule));
        Ok(())
      }
      AtRulePrelude::MozDocument => {
        let rules = self.parse_style_block(input)?;
        self.rules.0.push(CssRule::MozDocument(MozDocumentRule { rules, loc }));
        Ok(())
      }
      AtRulePrelude::Layer(names) => {
        let name = if names.is_empty() {
          None
        } else if names.len() == 1 {
          names.into_iter().next()
        } else {
          return Err(input.new_error(BasicParseErrorKind::AtRuleBodyInvalid));
        };

        let rules = self.parse_style_block(input)?;
        self.rules.0.push(CssRule::LayerBlock(LayerBlockRule { name, rules, loc }));
        Ok(())
      }
      AtRulePrelude::Property(name) => {
        self.rules.0.push(CssRule::Property(PropertyRule::parse(name, input, loc)?));
        Ok(())
      }
      AtRulePrelude::Import(..)
      | AtRulePrelude::Namespace(..)
      | AtRulePrelude::CustomMedia(..)
      | AtRulePrelude::Charset => {
        // These rules don't have blocks.
        Err(input.new_unexpected_token_error(Token::CurlyBracketBlock))
      }
      AtRulePrelude::StartingStyle => {
        let rules = self.parse_style_block(input)?;
        self.rules.0.push(CssRule::StartingStyle(StartingStyleRule { rules, loc }));
        Ok(())
      }
      AtRulePrelude::ViewTransition => {
        self
          .rules
          .0
          .push(CssRule::ViewTransition(ViewTransitionRule::parse(input, loc)?));
        Ok(())
      }
      AtRulePrelude::Nest(selectors) => {
        let (declarations, rules) = self.parse_nested(input, true)?;
        self.rules.0.push(CssRule::Nesting(NestingRule {
          style: StyleRule {
            selectors,
            declarations,
            vendor_prefix: VendorPrefix::empty(),
            rules,
            loc,
          },
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::FontFeatureValues(family_names) => {
        let rule = FontFeatureValuesRule::parse(family_names, input, loc, self.options)?;
        self.rules.0.push(CssRule::FontFeatureValues(rule));
        Ok(())
      }
      AtRulePrelude::Unknown(name, prelude) => {
        self.rules.0.push(CssRule::Unknown(UnknownAtRule {
          name,
          prelude,
          block: Some(TokenList::parse(input, &self.options, 0)?),
          loc,
        }));
        Ok(())
      }
      AtRulePrelude::Custom(prelude) => {
        self.rules.0.push(parse_custom_at_rule_body(
          prelude,
          input,
          start,
          self.options,
          self.at_rule_parser,
          self.is_in_style_rule,
        )?);
        Ok(())
      }
    }
  }
}

impl<'a, 'o, 'b, 'i, T: crate::traits::AtRuleParser<'i>> QualifiedRuleParser<'i>
  for NestedRuleParser<'a, 'o, 'i, T>
{
  type Prelude = SelectorList<'i>;
  type QualifiedRule = ();
  type Error = ParserError<'i>;

  fn parse_prelude<'t>(
    &mut self,
    input: &mut Parser<'i, 't>,
  ) -> Result<Self::Prelude, ParseError<'i, Self::Error>> {
    let selector_parser = SelectorParser {
      is_nesting_allowed: true,
      options: &self.options,
    };
    if self.is_in_style_rule {
      SelectorList::parse_relative(
        &selector_parser,
        input,
        ParseErrorRecovery::DiscardList,
        NestingRequirement::Implicit,
      )
    } else {
      SelectorList::parse(
        &selector_parser,
        input,
        ParseErrorRecovery::DiscardList,
        NestingRequirement::None,
      )
    }
  }

  fn parse_block<'t>(
    &mut self,
    selectors: Self::Prelude,
    start: &ParserState,
    input: &mut Parser<'i, 't>,
  ) -> Result<(), ParseError<'i, Self::Error>> {
    let loc = self.loc(start);
    let (declarations, rules) = self.parse_nested(input, true)?;
    self.rules.0.push(CssRule::Style(StyleRule {
      selectors,
      vendor_prefix: VendorPrefix::empty(),
      declarations,
      rules,
      loc,
    }));
    Ok(())
  }
}

/// Parse a declaration within {} block: `color: blue`
impl<'a, 'o, 'i, T: crate::traits::AtRuleParser<'i>> cssparser::DeclarationParser<'i>
  for NestedRuleParser<'a, 'o, 'i, T>
{
  type Declaration = ();
  type Error = ParserError<'i>;

  fn parse_value<'t>(
    &mut self,
    name: CowRcStr<'i>,
    input: &mut cssparser::Parser<'i, 't>,
  ) -> Result<Self::Declaration, cssparser::ParseError<'i, Self::Error>> {
    if self.rules.0.is_empty() {
      parse_declaration(
        name,
        input,
        &mut self.declarations,
        &mut self.important_declarations,
        &self.options,
      )
    } else if let Some(CssRule::NestedDeclarations(last)) = self.rules.0.last_mut() {
      parse_declaration(
        name,
        input,
        &mut last.declarations.declarations,
        &mut last.declarations.important_declarations,
        &self.options,
      )
    } else {
      let loc = self.loc(&input.state());
      let mut nested = NestedDeclarationsRule {
        declarations: DeclarationBlock::new(),
        loc,
      };

      parse_declaration(
        name,
        input,
        &mut nested.declarations.declarations,
        &mut nested.declarations.important_declarations,
        &self.options,
      )?;

      self.rules.0.push(CssRule::NestedDeclarations(nested));
      Ok(())
    }
  }
}

impl<'a, 'o, 'b, 'i, T: crate::traits::AtRuleParser<'i>> RuleBodyItemParser<'i, (), ParserError<'i>>
  for NestedRuleParser<'a, 'o, 'i, T>
{
  fn parse_qualified(&self) -> bool {
    true
  }

  fn parse_declarations(&self) -> bool {
    self.allow_declarations
  }
}

fn parse_custom_at_rule_prelude<'i, 't, T: crate::traits::AtRuleParser<'i>>(
  name: &CowRcStr<'i>,
  input: &mut Parser<'i, 't>,
  options: &ParserOptions<'_, 'i>,
  at_rule_parser: &mut T,
) -> Result<AtRulePrelude<'i, T::Prelude>, ParseError<'i, ParserError<'i>>> {
  match at_rule_parser.parse_prelude(name.clone(), input, options) {
    Ok(prelude) => return Ok(AtRulePrelude::Custom(prelude)),
    Err(ParseError {
      kind: ParseErrorKind::Basic(BasicParseErrorKind::AtRuleInvalid(..)),
      ..
    }) => {}
    Err(err) => {
      return Err(match &err.kind {
        ParseErrorKind::Basic(kind) => ParseError {
          kind: ParseErrorKind::Basic(kind.clone()),
          location: err.location,
        },
        _ => input.new_custom_error(ParserError::AtRulePreludeInvalid),
      })
    }
  }

  options.warn(input.new_error(BasicParseErrorKind::AtRuleInvalid(name.clone())));
  input.skip_whitespace();
  let tokens = TokenList::parse(input, &options, 0)?;
  Ok(AtRulePrelude::Unknown(name.into(), tokens))
}

fn parse_custom_at_rule_body<'i, 't, T: crate::traits::AtRuleParser<'i>>(
  prelude: T::Prelude,
  input: &mut Parser<'i, 't>,
  start: &ParserState,
  options: &ParserOptions<'_, 'i>,
  at_rule_parser: &mut T,
  is_nested: bool,
) -> Result<CssRule<'i, T::AtRule>, ParseError<'i, ParserError<'i>>> {
  at_rule_parser
    .parse_block(prelude, start, input, options, is_nested)
    .map(|prelude| CssRule::Custom(prelude))
    .map_err(|err| match &err.kind {
      ParseErrorKind::Basic(kind) => ParseError {
        kind: ParseErrorKind::Basic(kind.clone()),
        location: err.location,
      },
      _ => input.new_error(BasicParseErrorKind::AtRuleBodyInvalid),
    })
}

fn parse_custom_at_rule_without_block<'i, 't, T: crate::traits::AtRuleParser<'i>>(
  prelude: T::Prelude,
  start: &ParserState,
  options: &ParserOptions<'_, 'i>,
  at_rule_parser: &mut T,
  is_nested: bool,
) -> Result<CssRule<'i, T::AtRule>, ()> {
  at_rule_parser
    .rule_without_block(prelude, start, options, is_nested)
    .map(|prelude| CssRule::Custom(prelude))
}

pub fn parse_rule_list<'a, 'o, 'i, 't, T: crate::traits::AtRuleParser<'i>>(
  input: &mut Parser<'i, 't>,
  options: &'a ParserOptions<'o, 'i>,
  at_rule_parser: &mut T,
) -> Result<CssRuleList<'i, T::AtRule>, ParseError<'i, ParserError<'i>>> {
  let mut parser = NestedRuleParser {
    options,
    at_rule_parser,
    declarations: DeclarationList::new(),
    important_declarations: DeclarationList::new(),
    rules: &mut CssRuleList(Vec::new()),
    is_in_style_rule: false,
    allow_declarations: false,
  };

  let (_, rules) = parser.parse_nested(input, false)?;
  Ok(rules)
}

pub fn parse_style_block<'a, 'o, 'i, 't, T: crate::traits::AtRuleParser<'i>>(
  input: &mut Parser<'i, 't>,
  options: &'a ParserOptions<'o, 'i>,
  at_rule_parser: &mut T,
  is_nested: bool,
) -> Result<CssRuleList<'i, T::AtRule>, ParseError<'i, ParserError<'i>>> {
  let mut parser = NestedRuleParser {
    options,
    at_rule_parser,
    declarations: DeclarationList::new(),
    important_declarations: DeclarationList::new(),
    rules: &mut CssRuleList(Vec::new()),
    is_in_style_rule: is_nested,
    allow_declarations: true,
  };

  parser.parse_style_block(input)
}

#[inline]
pub fn starts_with_ignore_ascii_case(string: &str, prefix: &str) -> bool {
  string.len() >= prefix.len() && string.as_bytes()[0..prefix.len()].eq_ignore_ascii_case(prefix.as_bytes())
}
