//! CSS rules.
//!
//! The [CssRule](CssRule) enum includes all supported rules, and can be used to parse
//! and serialize rules from CSS. Lists of rules (i.e. within a stylesheet, or inside
//! another rule such as `@media`) are represented by [CssRuleList](CssRuleList).
//!
//! Each rule includes a source location, which indicates the line and column within
//! the source file where it was parsed. This is used when generating source maps.
//!
//! # Example
//!
//! This example shows how you could parse a single CSS rule, and serialize it to a string.
//!
//! ```
//! use lightningcss::{
//!   rules::CssRule,
//!   traits::ToCss,
//!   stylesheet::{ParserOptions, PrinterOptions}
//! };
//!
//! let rule = CssRule::parse_string(
//!   ".foo { color: red; }",
//!   ParserOptions::default()
//! ).unwrap();
//!
//! assert_eq!(
//!   rule.to_css_string(PrinterOptions::default()).unwrap(),
//!   ".foo {\n  color: red;\n}"
//! );
//! ```
//!
//! If you have a [cssparser::Parser](cssparser::Parser) already, you can also use the `parse` and `to_css`
//! methods instead, rather than parsing from a string.
//!
//! See [StyleSheet](super::stylesheet::StyleSheet) to parse an entire file of multiple rules.

#![deny(missing_docs)]

pub mod container;
pub mod counter_style;
pub mod custom_media;
pub mod document;
pub mod font_face;
pub mod font_feature_values;
pub mod font_palette_values;
pub mod import;
pub mod keyframes;
pub mod layer;
pub mod media;
pub mod namespace;
pub mod nesting;
pub mod page;
pub mod property;
pub mod scope;
pub mod starting_style;
pub mod style;
pub mod supports;
pub mod unknown;
pub mod view_transition;
pub mod viewport;

use self::font_feature_values::FontFeatureValuesRule;
use self::font_palette_values::FontPaletteValuesRule;
use self::layer::{LayerBlockRule, LayerStatementRule};
use self::property::PropertyRule;
use crate::context::PropertyHandlerContext;
use crate::declaration::{DeclarationBlock, DeclarationHandler};
use crate::dependencies::{Dependency, ImportDependency};
use crate::error::{MinifyError, ParserError, PrinterError, PrinterErrorKind};
use crate::parser::{parse_rule_list, parse_style_block, DefaultAtRule, DefaultAtRuleParser, TopLevelRuleParser};
use crate::prefixes::Feature;
use crate::printer::Printer;
use crate::rules::keyframes::KeyframesName;
use crate::selector::{is_compatible, is_equivalent, Component, Selector, SelectorList};
use crate::stylesheet::ParserOptions;
use crate::targets::TargetsWithSupportsScope;
use crate::traits::{AtRuleParser, ToCss};
use crate::values::string::CowArcStr;
use crate::vendor_prefix::VendorPrefix;
#[cfg(feature = "visitor")]
use crate::visitor::{Visit, VisitTypes, Visitor};
use container::ContainerRule;
use counter_style::CounterStyleRule;
use cssparser::{parse_one_rule, ParseError, Parser, ParserInput};
use custom_media::CustomMediaRule;
use document::MozDocumentRule;
use font_face::FontFaceRule;
use import::ImportRule;
use itertools::Itertools;
use keyframes::KeyframesRule;
use media::MediaRule;
use namespace::NamespaceRule;
use nesting::{NestedDeclarationsRule, NestingRule};
use page::PageRule;
use scope::ScopeRule;
use smallvec::{smallvec, SmallVec};
use starting_style::StartingStyleRule;
use std::collections::{HashMap, HashSet};
use std::hash::{BuildHasherDefault, Hasher};
use style::StyleRule;
use supports::SupportsRule;
use unknown::UnknownAtRule;
use view_transition::ViewTransitionRule;
use viewport::ViewportRule;

#[derive(Clone)]
pub(crate) struct StyleContext<'a, 'i> {
  pub selectors: &'a SelectorList<'i>,
  pub parent: Option<&'a StyleContext<'a, 'i>>,
}

/// A source location.
#[derive(PartialEq, Eq, Debug, Clone, Copy)]
#[cfg_attr(any(feature = "serde", feature = "nodejs"), derive(serde::Serialize))]
#[cfg_attr(feature = "serde", derive(serde::Deserialize))]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
pub struct Location {
  /// The index of the source file within the source map.
  pub source_index: u32,
  /// The line number, starting at 0.
  pub line: u32,
  /// The column number within a line, starting at 1 for first the character of the line.
  /// Column numbers are counted in UTF-16 code units.
  pub column: u32,
}

/// A CSS rule.
#[derive(Debug, PartialEq, Clone)]
#[cfg_attr(feature = "visitor", derive(Visit))]
#[cfg_attr(feature = "visitor", visit(visit_rule, RULES))]
#[cfg_attr(
  feature = "serde",
  derive(serde::Serialize),
  serde(tag = "type", content = "value", rename_all = "kebab-case")
)]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema), schemars(rename = "Rule"))]
#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
pub enum CssRule<'i, R = DefaultAtRule> {
  /// A `@media` rule.
  #[cfg_attr(feature = "serde", serde(borrow))]
  Media(MediaRule<'i, R>),
  /// An `@import` rule.
  Import(ImportRule<'i>),
  /// A style rule.
  Style(StyleRule<'i, R>),
  /// A `@keyframes` rule.
  Keyframes(KeyframesRule<'i>),
  /// A `@font-face` rule.
  FontFace(FontFaceRule<'i>),
  /// A `@font-palette-values` rule.
  FontPaletteValues(FontPaletteValuesRule<'i>),
  /// A `@font-feature-values` rule.
  FontFeatureValues(FontFeatureValuesRule<'i>),
  /// A `@page` rule.
  Page(PageRule<'i>),
  /// A `@supports` rule.
  Supports(SupportsRule<'i, R>),
  /// A `@counter-style` rule.
  CounterStyle(CounterStyleRule<'i>),
  /// A `@namespace` rule.
  Namespace(NamespaceRule<'i>),
  /// A `@-moz-document` rule.
  MozDocument(MozDocumentRule<'i, R>),
  /// A `@nest` rule.
  Nesting(NestingRule<'i, R>),
  /// A nested declarations rule.
  NestedDeclarations(NestedDeclarationsRule<'i>),
  /// A `@viewport` rule.
  Viewport(ViewportRule<'i>),
  /// A `@custom-media` rule.
  CustomMedia(CustomMediaRule<'i>),
  /// A `@layer` statement rule.
  LayerStatement(LayerStatementRule<'i>),
  /// A `@layer` block rule.
  LayerBlock(LayerBlockRule<'i, R>),
  /// A `@property` rule.
  Property(PropertyRule<'i>),
  /// A `@container` rule.
  Container(ContainerRule<'i, R>),
  /// A `@scope` rule.
  Scope(ScopeRule<'i, R>),
  /// A `@starting-style` rule.
  StartingStyle(StartingStyleRule<'i, R>),
  /// A `@view-transition` rule.
  ViewTransition(ViewTransitionRule<'i>),
  /// A placeholder for a rule that was removed.
  Ignored,
  /// An unknown at-rule.
  Unknown(UnknownAtRule<'i>),
  /// A custom at-rule.
  Custom(R),
}

// Manually implemented deserialize to reduce binary size.
#[cfg(feature = "serde")]
#[cfg_attr(docsrs, doc(cfg(feature = "serde")))]
impl<'i, 'de: 'i, R: serde::Deserialize<'de>> serde::Deserialize<'de> for CssRule<'i, R> {
  fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
  where
    D: serde::Deserializer<'de>,
  {
    #[derive(serde::Deserialize)]
    #[serde(field_identifier, rename_all = "snake_case")]
    enum Field {
      Type,
      Value,
    }

    struct PartialRule<'de> {
      rule_type: CowArcStr<'de>,
      content: serde::__private::de::Content<'de>,
    }

    struct CssRuleVisitor;

    impl<'de> serde::de::Visitor<'de> for CssRuleVisitor {
      type Value = PartialRule<'de>;

      fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
        formatter.write_str("a CssRule")
      }

      fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
      where
        A: serde::de::MapAccess<'de>,
      {
        let mut rule_type: Option<CowArcStr<'de>> = None;
        let mut value: Option<serde::__private::de::Content> = None;
        while let Some(key) = map.next_key()? {
          match key {
            Field::Type => {
              rule_type = Some(map.next_value()?);
            }
            Field::Value => {
              value = Some(map.next_value()?);
            }
          }
        }

        let rule_type = rule_type.ok_or_else(|| serde::de::Error::missing_field("type"))?;
        let content = value.ok_or_else(|| serde::de::Error::missing_field("value"))?;
        Ok(PartialRule { rule_type, content })
      }
    }

    let partial = deserializer.deserialize_map(CssRuleVisitor)?;
    let deserializer = serde::__private::de::ContentDeserializer::new(partial.content);

    match partial.rule_type.as_ref() {
      "media" => {
        let rule = MediaRule::deserialize(deserializer)?;
        Ok(CssRule::Media(rule))
      }
      "import" => {
        let rule = ImportRule::deserialize(deserializer)?;
        Ok(CssRule::Import(rule))
      }
      "style" => {
        let rule = StyleRule::deserialize(deserializer)?;
        Ok(CssRule::Style(rule))
      }
      "keyframes" => {
        let rule = KeyframesRule::deserialize(deserializer)?;
        Ok(CssRule::Keyframes(rule))
      }
      "font-face" => {
        let rule = FontFaceRule::deserialize(deserializer)?;
        Ok(CssRule::FontFace(rule))
      }
      "font-palette-values" => {
        let rule = FontPaletteValuesRule::deserialize(deserializer)?;
        Ok(CssRule::FontPaletteValues(rule))
      }
      "font-feature-values" => {
        let rule = FontFeatureValuesRule::deserialize(deserializer)?;
        Ok(CssRule::FontFeatureValues(rule))
      }
      "page" => {
        let rule = PageRule::deserialize(deserializer)?;
        Ok(CssRule::Page(rule))
      }
      "supports" => {
        let rule = SupportsRule::deserialize(deserializer)?;
        Ok(CssRule::Supports(rule))
      }
      "counter-style" => {
        let rule = CounterStyleRule::deserialize(deserializer)?;
        Ok(CssRule::CounterStyle(rule))
      }
      "namespace" => {
        let rule = NamespaceRule::deserialize(deserializer)?;
        Ok(CssRule::Namespace(rule))
      }
      "moz-document" => {
        let rule = MozDocumentRule::deserialize(deserializer)?;
        Ok(CssRule::MozDocument(rule))
      }
      "nesting" => {
        let rule = NestingRule::deserialize(deserializer)?;
        Ok(CssRule::Nesting(rule))
      }
      "nested-declarations" => {
        let rule = NestedDeclarationsRule::deserialize(deserializer)?;
        Ok(CssRule::NestedDeclarations(rule))
      }
      "viewport" => {
        let rule = ViewportRule::deserialize(deserializer)?;
        Ok(CssRule::Viewport(rule))
      }
      "custom-media" => {
        let rule = CustomMediaRule::deserialize(deserializer)?;
        Ok(CssRule::CustomMedia(rule))
      }
      "layer-statement" => {
        let rule = LayerStatementRule::deserialize(deserializer)?;
        Ok(CssRule::LayerStatement(rule))
      }
      "layer-block" => {
        let rule = LayerBlockRule::deserialize(deserializer)?;
        Ok(CssRule::LayerBlock(rule))
      }
      "property" => {
        let rule = PropertyRule::deserialize(deserializer)?;
        Ok(CssRule::Property(rule))
      }
      "container" => {
        let rule = ContainerRule::deserialize(deserializer)?;
        Ok(CssRule::Container(rule))
      }
      "scope" => {
        let rule = ScopeRule::deserialize(deserializer)?;
        Ok(CssRule::Scope(rule))
      }
      "starting-style" => {
        let rule = StartingStyleRule::deserialize(deserializer)?;
        Ok(CssRule::StartingStyle(rule))
      }
      "view-transition" => {
        let rule = ViewTransitionRule::deserialize(deserializer)?;
        Ok(CssRule::ViewTransition(rule))
      }
      "ignored" => Ok(CssRule::Ignored),
      "unknown" => {
        let rule = UnknownAtRule::deserialize(deserializer)?;
        Ok(CssRule::Unknown(rule))
      }
      "custom" => {
        let rule = R::deserialize(deserializer)?;
        Ok(CssRule::Custom(rule))
      }
      t => Err(serde::de::Error::unknown_variant(t, &[])),
    }
  }
}

impl<'a, 'i, T: ToCss> ToCss for CssRule<'i, T> {
  fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
  where
    W: std::fmt::Write,
  {
    match self {
      CssRule::Media(media) => media.to_css(dest),
      CssRule::Import(import) => import.to_css(dest),
      CssRule::Style(style) => style.to_css(dest),
      CssRule::Keyframes(keyframes) => keyframes.to_css(dest),
      CssRule::FontFace(font_face) => font_face.to_css(dest),
      CssRule::FontPaletteValues(f) => f.to_css(dest),
      CssRule::FontFeatureValues(font_feature_values) => font_feature_values.to_css(dest),
      CssRule::Page(font_face) => font_face.to_css(dest),
      CssRule::Supports(supports) => supports.to_css(dest),
      CssRule::CounterStyle(counter_style) => counter_style.to_css(dest),
      CssRule::Namespace(namespace) => namespace.to_css(dest),
      CssRule::MozDocument(document) => document.to_css(dest),
      CssRule::Nesting(nesting) => nesting.to_css(dest),
      CssRule::NestedDeclarations(nested) => nested.to_css(dest),
      CssRule::Viewport(viewport) => viewport.to_css(dest),
      CssRule::CustomMedia(custom_media) => custom_media.to_css(dest),
      CssRule::LayerStatement(layer) => layer.to_css(dest),
      CssRule::LayerBlock(layer) => layer.to_css(dest),
      CssRule::Property(property) => property.to_css(dest),
      CssRule::StartingStyle(rule) => rule.to_css(dest),
      CssRule::Container(container) => container.to_css(dest),
      CssRule::Scope(scope) => scope.to_css(dest),
      CssRule::ViewTransition(rule) => rule.to_css(dest),
      CssRule::Unknown(unknown) => unknown.to_css(dest),
      CssRule::Custom(rule) => rule.to_css(dest).map_err(|_| PrinterError {
        kind: PrinterErrorKind::FmtError,
        loc: None,
      }),
      CssRule::Ignored => Ok(()),
    }
  }
}

impl<'i> CssRule<'i, DefaultAtRule> {
  /// Parse a single rule.
  pub fn parse<'t>(
    input: &mut Parser<'i, 't>,
    options: &ParserOptions<'_, 'i>,
  ) -> Result<Self, ParseError<'i, ParserError<'i>>> {
    Self::parse_with(input, options, &mut DefaultAtRuleParser)
  }

  /// Parse a single rule from a string.
  pub fn parse_string(
    input: &'i str,
    options: ParserOptions<'_, 'i>,
  ) -> Result<Self, ParseError<'i, ParserError<'i>>> {
    Self::parse_string_with(input, options, &mut DefaultAtRuleParser)
  }
}

impl<'i, T> CssRule<'i, T> {
  /// Parse a single rule.
  pub fn parse_with<'t, P: AtRuleParser<'i, AtRule = T>>(
    input: &mut Parser<'i, 't>,
    options: &ParserOptions<'_, 'i>,
    at_rule_parser: &mut P,
  ) -> Result<Self, ParseError<'i, ParserError<'i>>> {
    let mut rules = CssRuleList(Vec::new());
    parse_one_rule(input, &mut TopLevelRuleParser::new(options, at_rule_parser, &mut rules))?;
    Ok(rules.0.pop().unwrap())
  }

  /// Parse a single rule from a string.
  pub fn parse_string_with<P: AtRuleParser<'i, AtRule = T>>(
    input: &'i str,
    options: ParserOptions<'_, 'i>,
    at_rule_parser: &mut P,
  ) -> Result<Self, ParseError<'i, ParserError<'i>>> {
    let mut input = ParserInput::new(input);
    let mut parser = Parser::new(&mut input);
    Self::parse_with(&mut parser, &options, at_rule_parser)
  }
}

/// A list of CSS rules.
#[derive(Debug, PartialEq, Clone, Default)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize), serde(transparent))]
#[cfg_attr(feature = "jsonschema", derive(schemars::JsonSchema))]
#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
pub struct CssRuleList<'i, R = DefaultAtRule>(
  #[cfg_attr(feature = "serde", serde(borrow))] pub Vec<CssRule<'i, R>>,
);

impl<'i> CssRuleList<'i, DefaultAtRule> {
  /// Parse a rule list.
  pub fn parse<'t>(
    input: &mut Parser<'i, 't>,
    options: &ParserOptions<'_, 'i>,
  ) -> Result<Self, ParseError<'i, ParserError<'i>>> {
    Self::parse_with(input, options, &mut DefaultAtRuleParser)
  }

  /// Parse a style block, with both declarations and rules.
  /// Resulting declarations are returned in a nested style rule.
  pub fn parse_style_block<'t>(
    input: &mut Parser<'i, 't>,
    options: &ParserOptions<'_, 'i>,
    is_nested: bool,
  ) -> Result<Self, ParseError<'i, ParserError<'i>>> {
    Self::parse_style_block_with(input, options, &mut DefaultAtRuleParser, is_nested)
  }
}

impl<'i, T> CssRuleList<'i, T> {
  /// Parse a rule list with a custom at rule parser.
  pub fn parse_with<'t, P: AtRuleParser<'i, AtRule = T>>(
    input: &mut Parser<'i, 't>,
    options: &ParserOptions<'_, 'i>,
    at_rule_parser: &mut P,
  ) -> Result<Self, ParseError<'i, ParserError<'i>>> {
    parse_rule_list(input, options, at_rule_parser)
  }

  /// Parse a style block, with both declarations and rules.
  /// Resulting declarations are returned in a nested style rule.
  pub fn parse_style_block_with<'t, P: AtRuleParser<'i, AtRule = T>>(
    input: &mut Parser<'i, 't>,
    options: &ParserOptions<'_, 'i>,
    at_rule_parser: &mut P,
    is_nested: bool,
  ) -> Result<Self, ParseError<'i, ParserError<'i>>> {
    parse_style_block(input, options, at_rule_parser, is_nested)
  }
}

// Manually implemented to avoid circular child types.
#[cfg(feature = "visitor")]
#[cfg_attr(docsrs, doc(cfg(feature = "visitor")))]
impl<'i, T: Visit<'i, T, V>, V: ?Sized + Visitor<'i, T>> Visit<'i, T, V> for CssRuleList<'i, T> {
  const CHILD_TYPES: VisitTypes = VisitTypes::all();

  fn visit(&mut self, visitor: &mut V) -> Result<(), V::Error> {
    if visitor.visit_types().contains(VisitTypes::RULES) {
      visitor.visit_rule_list(self)
    } else {
      self.0.visit(visitor)
    }
  }

  fn visit_children(&mut self, visitor: &mut V) -> Result<(), V::Error> {
    self.0.visit(visitor)
  }
}

pub(crate) struct MinifyContext<'a, 'i> {
  pub targets: TargetsWithSupportsScope,
  pub handler: &'a mut DeclarationHandler<'i>,
  pub important_handler: &'a mut DeclarationHandler<'i>,
  pub handler_context: PropertyHandlerContext<'i, 'a>,
  pub unused_symbols: &'a HashSet<String>,
  pub custom_media: Option<HashMap<CowArcStr<'i>, CustomMediaRule<'i>>>,
  pub css_modules: bool,
  pub pure_css_modules: bool,
}

impl<'i, T: Clone> CssRuleList<'i, T> {
  pub(crate) fn minify(
    &mut self,
    context: &mut MinifyContext<'_, 'i>,
    parent_is_unused: bool,
  ) -> Result<(), MinifyError> {
    let mut keyframe_rules = HashMap::new();
    let mut layer_rules = HashMap::new();
    let mut has_layers = false;
    let mut property_rules = HashMap::new();
    let mut font_feature_values_rules = Vec::new();
    let mut style_rules =
      HashMap::with_capacity_and_hasher(self.0.len(), BuildHasherDefault::<PrecomputedHasher>::default());
    let mut rules = Vec::new();
    for mut rule in self.0.drain(..) {
      match &mut rule {
        CssRule::Keyframes(keyframes) => {
          if context.unused_symbols.contains(match &keyframes.name {
            KeyframesName::Ident(ident) => ident.0.as_ref(),
            KeyframesName::Custom(string) => string.as_ref(),
          }) {
            continue;
          }
          keyframes.minify(context);

          macro_rules! set_prefix {
            ($keyframes: ident) => {
              $keyframes.vendor_prefix =
                context.targets.current.prefixes($keyframes.vendor_prefix, Feature::AtKeyframes);
            };
          }

          // Merge @keyframes rules with the same name.
          if let Some(existing_idx) = keyframe_rules.get(&keyframes.name) {
            if let Some(CssRule::Keyframes(existing)) = &mut rules.get_mut(*existing_idx) {
              // If the existing rule has the same vendor prefixes, replace it with this rule.
              if existing.vendor_prefix == keyframes.vendor_prefix {
                *existing = keyframes.clone();
                continue;
              }
              // Otherwise, if the keyframes are identical, merge the prefixes.
              if existing.keyframes == keyframes.keyframes {
                existing.vendor_prefix |= keyframes.vendor_prefix;
                set_prefix!(existing);
                continue;
              }
            }
          }

          set_prefix!(keyframes);
          keyframe_rules.insert(keyframes.name.clone(), rules.len());

          let fallbacks = keyframes.get_fallbacks(&context.targets.current);
          rules.push(rule);
          rules.extend(fallbacks);
          continue;
        }
        CssRule::CustomMedia(_) => {
          if context.custom_media.is_some() {
            continue;
          }
        }
        CssRule::Media(media) => {
          if let Some(CssRule::Media(last_rule)) = rules.last_mut() {
            if last_rule.query == media.query {
              last_rule.rules.0.extend(media.rules.0.drain(..));
              last_rule.minify(context, parent_is_unused)?;
              continue;
            }
          }

          if media.minify(context, parent_is_unused)? {
            continue;
          }
        }
        CssRule::Supports(supports) => {
          if let Some(CssRule::Supports(last_rule)) = rules.last_mut() {
            if last_rule.condition == supports.condition {
              last_rule.rules.0.extend(supports.rules.0.drain(..));
              last_rule.minify(context, parent_is_unused)?;
              continue;
            }
          }

          supports.minify(context, parent_is_unused)?;
          if supports.rules.0.is_empty() {
            continue;
          }
        }
        CssRule::Container(container) => {
          if let Some(CssRule::Container(last_rule)) = rules.last_mut() {
            if last_rule.name == container.name && last_rule.condition == container.condition {
              last_rule.rules.0.extend(container.rules.0.drain(..));
              last_rule.minify(context, parent_is_unused)?;
              continue;
            }
          }

          if container.minify(context, parent_is_unused)? {
            continue;
          }
        }
        CssRule::LayerBlock(layer) => {
          // Merging non-adjacent layer rules is safe because they are applied
          // in the order they are first defined.
          if let Some(name) = &layer.name {
            if let Some(idx) = layer_rules.get(name) {
              if let Some(CssRule::LayerBlock(last_rule)) = rules.get_mut(*idx) {
                last_rule.rules.0.extend(layer.rules.0.drain(..));
                continue;
              }
            }

            layer_rules.insert(name.clone(), rules.len());
            has_layers = true;
          }
        }
        CssRule::LayerStatement(layer) => {
          // Create @layer block rules for each declared layer name,
          // so we can merge other blocks into it later on.
          for name in &layer.names {
            if !layer_rules.contains_key(name) {
              layer_rules.insert(name.clone(), rules.len());
              has_layers = true;
              rules.push(CssRule::LayerBlock(LayerBlockRule {
                name: Some(name.clone()),
                rules: CssRuleList(vec![]),
                loc: layer.loc.clone(),
              }));
            }
          }
          continue;
        }
        CssRule::MozDocument(document) => document.minify(context)?,
        CssRule::Style(style) => {
          if parent_is_unused || style.minify(context, parent_is_unused)? {
            continue;
          }

          // If some of the selectors in this rule are not compatible with the targets,
          // we need to either wrap in :is() or split them into multiple rules.
          let incompatible = if style.selectors.0.len() > 1
            && context.targets.current.should_compile_selectors()
            && !style.is_compatible(context.targets.current)
          {
            // The :is() selector accepts a forgiving selector list, so use that if possible.
            // Note that :is() does not allow pseudo elements, so we need to check for that.
            // In addition, :is() takes the highest specificity of its arguments, so if the selectors
            // have different weights, we need to split them into separate rules as well.
            if context.targets.current.is_compatible(crate::compat::Feature::IsSelector)
              && !style.selectors.0.iter().any(|selector| selector.has_pseudo_element())
              && style.selectors.0.iter().map(|selector| selector.specificity()).all_equal()
            {
              style.selectors =
                SelectorList::new(smallvec![
                  Component::Is(style.selectors.0.clone().into_boxed_slice()).into()
                ]);
              smallvec![]
            } else {
              // Otherwise, partition the selectors and keep the compatible ones in this rule.
              // We will generate additional rules for incompatible selectors later.
              let (compatible, incompatible) = style
                .selectors
                .0
                .iter()
                .cloned()
                .partition::<SmallVec<[Selector; 1]>, _>(|selector| {
                  let list = SelectorList::new(smallvec![selector.clone()]);
                  is_compatible(&list.0, context.targets.current)
                });
              style.selectors = SelectorList::new(compatible);
              incompatible
            }
          } else {
            smallvec![]
          };

          style.update_prefix(context);

          // Attempt to merge the new rule with the last rule we added.
          let mut merged = false;
          if let Some(CssRule::Style(last_style_rule)) = rules.last_mut() {
            if merge_style_rules(style, last_style_rule, context) {
              // If that was successful, then the last rule has been updated to include the
              // selectors/declarations of the new rule. This might mean that we can merge it
              // with the previous rule, so continue trying while we have style rules available.
              while rules.len() >= 2 {
                let len = rules.len();
                let (a, b) = rules.split_at_mut(len - 1);
                if let (CssRule::Style(last), CssRule::Style(prev)) = (&mut b[0], &mut a[len - 2]) {
                  if merge_style_rules(last, prev, context) {
                    // If we were able to merge the last rule into the previous one, remove the last.
                    rules.pop();
                    continue;
                  }
                }
                // If we didn't see a style rule, or were unable to merge, stop.
                break;
              }
              merged = true;
            }
          }

          // Create additional rules for logical properties, @supports overrides, and incompatible selectors.
          let supports = context.handler_context.get_supports_rules(&style);
          let logical = context.handler_context.get_additional_rules(&style);

          let incompatible_rules = incompatible
            .into_iter()
            .map(|selector| {
              // Create a clone of the rule with only the one incompatible selector.
              let list = SelectorList::new(smallvec![selector]);
              let mut clone = style.clone();
              clone.selectors = list;
              clone.update_prefix(context);

              // Also add rules for logical properties and @supports overrides.
              let supports = context.handler_context.get_supports_rules(&clone);
              let logical = context.handler_context.get_additional_rules(&clone);
              (clone, logical, supports)
            })
            .collect::<Vec<_>>();

          context.handler_context.reset();

          // If the rule has nested rules, and we have extra rules to insert such as for logical properties,
          // we need to split the rule in two so we can insert the extra rules in between the declarations from
          // the main rule and the nested rules.
          let nested_rule = if !style.rules.0.is_empty()
            // can happen if there are no compatible rules, above.
            && !style.selectors.0.is_empty()
            && (!logical.is_empty() || !supports.is_empty() || !incompatible_rules.is_empty())
          {
            let mut rules = CssRuleList(vec![]);
            std::mem::swap(&mut style.rules, &mut rules);
            Some(StyleRule {
              selectors: style.selectors.clone(),
              declarations: DeclarationBlock::default(),
              rules,
              vendor_prefix: style.vendor_prefix,
              loc: style.loc,
            })
          } else {
            None
          };

          if !merged && !style.is_empty() {
            let source_index = style.loc.source_index;
            let has_no_rules = style.rules.0.is_empty();
            let idx = rules.len();
            rules.push(rule);

            // Check if this rule is a duplicate of an earlier rule, meaning it has
            // the same selectors and defines the same properties. If so, remove the
            // earlier rule because this one completely overrides it.
            if has_no_rules {
              // SAFETY: StyleRuleKeys never live beyond this method.
              let key = StyleRuleKey::new(unsafe { &*(&rules as *const _) }, idx);
              if idx > 0 {
                if let Some(i) = style_rules.remove(&key) {
                  if let CssRule::Style(other) = &rules[i] {
                    // Don't remove the rule if this is a CSS module and the other rule came from a different file.
                    if !context.css_modules || source_index == other.loc.source_index {
                      // Only mark the rule as ignored so we don't need to change all of the indices.
                      rules[i] = CssRule::Ignored;
                    }
                  }
                }
              }

              style_rules.insert(key, idx);
            }
          }

          if !logical.is_empty() {
            let mut logical = CssRuleList(logical);
            logical.minify(context, parent_is_unused)?;
            rules.extend(logical.0)
          }

          rules.extend(supports);
          for (rule, logical, supports) in incompatible_rules {
            if !rule.is_empty() {
              rules.push(CssRule::Style(rule));
            }
            if !logical.is_empty() {
              let mut logical = CssRuleList(logical);
              logical.minify(context, parent_is_unused)?;
              rules.extend(logical.0)
            }
            rules.extend(supports);
          }

          if let Some(nested_rule) = nested_rule {
            rules.push(CssRule::Style(nested_rule));
          }

          continue;
        }
        CssRule::CounterStyle(counter_style) => {
          if context.unused_symbols.contains(counter_style.name.0.as_ref()) {
            continue;
          }
        }
        CssRule::Scope(scope) => scope.minify(context)?,
        CssRule::Nesting(nesting) => {
          if nesting.minify(context, parent_is_unused)? {
            continue;
          }
        }
        CssRule::NestedDeclarations(nested) => {
          if nested.minify(context, parent_is_unused) {
            continue;
          }
        }
        CssRule::StartingStyle(rule) => {
          if rule.minify(context, parent_is_unused)? {
            continue;
          }
        }
        CssRule::FontPaletteValues(f) => {
          if context.unused_symbols.contains(f.name.0.as_ref()) {
            continue;
          }

          f.minify(context, parent_is_unused);

          let fallbacks = f.get_fallbacks(context.targets.current);
          rules.push(rule);
          rules.extend(fallbacks);
          continue;
        }
        CssRule::FontFeatureValues(rule) => {
          if let Some(index) = font_feature_values_rules
            .iter()
            .find(|index| matches!(&rules[**index], CssRule::FontFeatureValues(r) if r.name == rule.name))
          {
            if let CssRule::FontFeatureValues(existing) = &mut rules[*index] {
              existing.merge(rule);
            }
            continue;
          } else {
            font_feature_values_rules.push(rules.len());
          }
        }
        CssRule::Property(property) => {
          if context.unused_symbols.contains(property.name.0.as_ref()) {
            continue;
          }

          if let Some(index) = property_rules.get(&property.name) {
            rules[*index] = rule;
            continue;
          } else {
            property_rules.insert(property.name.clone(), rules.len());
          }
        }
        CssRule::Import(_) => {
          // @layer blocks can't be inlined into layers declared before imports.
          layer_rules.clear();
        }
        _ => {}
      }

      rules.push(rule)
    }

    // Optimize @layer rules. Combine subsequent empty layer blocks into a single @layer statement
    // so that layers are declared in the correct order.
    if has_layers {
      let mut declared_layers = HashSet::new();
      let mut layer_statement = None;
      for index in 0..rules.len() {
        match &mut rules[index] {
          CssRule::LayerBlock(layer) => {
            if layer.minify(context, parent_is_unused)? {
              if let Some(name) = &layer.name {
                if declared_layers.contains(name) {
                  // Remove empty layer that has already been declared.
                  rules[index] = CssRule::Ignored;
                  continue;
                }

                let name = name.clone();
                declared_layers.insert(name.clone());

                if let Some(layer_index) = layer_statement {
                  if let CssRule::LayerStatement(layer) = &mut rules[layer_index] {
                    // Add name to previous layer statement rule and remove this one.
                    layer.names.push(name);
                    rules[index] = CssRule::Ignored;
                  }
                } else {
                  // Create a new layer statement rule to declare the name.
                  rules[index] = CssRule::LayerStatement(LayerStatementRule {
                    names: vec![name],
                    loc: layer.loc,
                  });
                  layer_statement = Some(index);
                }
              } else {
                // Remove empty anonymous layer.
                rules[index] = CssRule::Ignored;
              }
            } else {
              // Non-empty @layer block. Start a new statement.
              layer_statement = None;
            }
          }
          CssRule::Import(import) => {
            if let Some(layer) = &import.layer {
              // Start a new @layer statement so the import layer is in the right order.
              layer_statement = None;
              if let Some(name) = layer {
                declared_layers.insert(name.clone());
              }
            }
          }
          _ => {}
        }
      }
    }

    self.0 = rules;
    Ok(())
  }
}

fn merge_style_rules<'i, T>(
  style: &mut StyleRule<'i, T>,
  last_style_rule: &mut StyleRule<'i, T>,
  context: &mut MinifyContext<'_, 'i>,
) -> bool {
  // Merge declarations if the selectors are equivalent, and both are compatible with all targets.
  if style.selectors == last_style_rule.selectors
    && style.is_compatible(context.targets.current)
    && last_style_rule.is_compatible(context.targets.current)
    && style.rules.0.is_empty()
    && last_style_rule.rules.0.is_empty()
    && (!context.css_modules || style.loc.source_index == last_style_rule.loc.source_index)
  {
    last_style_rule
      .declarations
      .declarations
      .extend(style.declarations.declarations.drain(..));
    last_style_rule
      .declarations
      .important_declarations
      .extend(style.declarations.important_declarations.drain(..));
    last_style_rule
      .declarations
      .minify(context.handler, context.important_handler, &mut context.handler_context);
    return true;
  } else if style.declarations == last_style_rule.declarations
    && style.rules.0.is_empty()
    && last_style_rule.rules.0.is_empty()
  {
    // If both selectors are potentially vendor prefixable, and they are
    // equivalent minus prefixes, add the prefix to the last rule.
    if !style.vendor_prefix.is_empty()
      && !last_style_rule.vendor_prefix.is_empty()
      && is_equivalent(&style.selectors.0, &last_style_rule.selectors.0)
    {
      // If the new rule is unprefixed, replace the prefixes of the last rule.
      // Otherwise, add the new prefix.
      if style.vendor_prefix.contains(VendorPrefix::None) && context.targets.current.should_compile_selectors() {
        last_style_rule.vendor_prefix = style.vendor_prefix;
      } else {
        last_style_rule.vendor_prefix |= style.vendor_prefix;
      }
      return true;
    }

    // Append the selectors to the last rule if the declarations are the same, and all selectors are compatible.
    if style.is_compatible(context.targets.current) && last_style_rule.is_compatible(context.targets.current) {
      last_style_rule.selectors.0.extend(style.selectors.0.drain(..));
      if style.vendor_prefix.contains(VendorPrefix::None) && context.targets.current.should_compile_selectors() {
        last_style_rule.vendor_prefix = style.vendor_prefix;
      } else {
        last_style_rule.vendor_prefix |= style.vendor_prefix;
      }
      return true;
    }
  }
  false
}

impl<'a, 'i, T: ToCss> ToCss for CssRuleList<'i, T> {
  fn to_css<W>(&self, dest: &mut Printer<W>) -> Result<(), PrinterError>
  where
    W: std::fmt::Write,
  {
    let mut first = true;
    let mut last_without_block = false;

    for rule in &self.0 {
      if let CssRule::Ignored = &rule {
        continue;
      }

      // Skip @import rules if collecting dependencies.
      if let CssRule::Import(rule) = &rule {
        if dest.remove_imports {
          let dep = if dest.dependencies.is_some() {
            Some(Dependency::Import(ImportDependency::new(&rule, dest.filename())))
          } else {
            None
          };

          if let Some(dependencies) = &mut dest.dependencies {
            dependencies.push(dep.unwrap());
            continue;
          }
        }
      }

      if first {
        first = false;
      } else {
        if !dest.minify
          && !(last_without_block
            && matches!(
              rule,
              CssRule::Import(..) | CssRule::Namespace(..) | CssRule::LayerStatement(..)
            ))
        {
          dest.write_char('\n')?;
        }
        dest.newline()?;
      }
      rule.to_css(dest)?;
      last_without_block = matches!(
        rule,
        CssRule::Import(..) | CssRule::Namespace(..) | CssRule::LayerStatement(..)
      );
    }

    Ok(())
  }
}

impl<'i, T> std::ops::Index<usize> for CssRuleList<'i, T> {
  type Output = CssRule<'i, T>;

  fn index(&self, index: usize) -> &Self::Output {
    &self.0[index]
  }
}

impl<'i, T> std::ops::IndexMut<usize> for CssRuleList<'i, T> {
  fn index_mut(&mut self, index: usize) -> &mut Self::Output {
    &mut self.0[index]
  }
}

/// A hasher that expects to be called with a single u64, which is already a hash.
#[derive(Default)]
struct PrecomputedHasher {
  hash: Option<u64>,
}

impl Hasher for PrecomputedHasher {
  #[inline]
  fn write(&mut self, _: &[u8]) {
    unreachable!()
  }

  #[inline]
  fn write_u64(&mut self, i: u64) {
    debug_assert!(self.hash.is_none());
    self.hash = Some(i);
  }

  #[inline]
  fn finish(&self) -> u64 {
    self.hash.unwrap()
  }
}

/// A key to a StyleRule meant for use in a HashMap for quickly detecting duplicates.
/// It stores a reference to a list and an index so it can access items without cloning
/// even when the list is reallocated. A hash is also pre-computed for fast lookups.
#[derive(Clone)]
pub(crate) struct StyleRuleKey<'a, 'i, R> {
  list: &'a Vec<CssRule<'i, R>>,
  index: usize,
  hash: u64,
}

impl<'a, 'i, R> StyleRuleKey<'a, 'i, R> {
  fn new(list: &'a Vec<CssRule<'i, R>>, index: usize) -> Self {
    let rule = match &list[index] {
      CssRule::Style(style) => style,
      _ => unreachable!(),
    };

    Self {
      list,
      index,
      hash: rule.hash_key(),
    }
  }
}

impl<'a, 'i, R> PartialEq for StyleRuleKey<'a, 'i, R> {
  fn eq(&self, other: &Self) -> bool {
    let rule = match self.list.get(self.index) {
      Some(CssRule::Style(style)) => style,
      _ => return false,
    };

    let other_rule = match other.list.get(other.index) {
      Some(CssRule::Style(style)) => style,
      _ => return false,
    };

    rule.is_duplicate(other_rule)
  }
}

impl<'a, 'i, R> Eq for StyleRuleKey<'a, 'i, R> {}

impl<'a, 'i, R> std::hash::Hash for StyleRuleKey<'a, 'i, R> {
  fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
    state.write_u64(self.hash);
  }
}
