//! CSS style sheets and style attributes.
//!
//! A [StyleSheet](StyleSheet) represents a `.css` file or `<style>` element in HTML.
//! A [StyleAttribute](StyleAttribute) represents an inline `style` attribute in HTML.

use crate::context::{DeclarationContext, PropertyHandlerContext};
use crate::css_modules::{hash, CssModule, CssModuleExports, CssModuleReferences};
use crate::declaration::{DeclarationBlock, DeclarationHandler};
use crate::dependencies::Dependency;
use crate::error::{Error, ErrorLocation, MinifyErrorKind, ParserError, PrinterError, PrinterErrorKind};
use crate::parser::{DefaultAtRule, DefaultAtRuleParser, TopLevelRuleParser};
use crate::printer::Printer;
use crate::rules::{CssRule, CssRuleList, MinifyContext};
use crate::targets::{should_compile, Targets, TargetsWithSupportsScope};
use crate::traits::{AtRuleParser, ToCss};
use crate::values::string::CowArcStr;
#[cfg(feature = "visitor")]
use crate::visitor::{Visit, VisitTypes, Visitor};
use cssparser::{Parser, ParserInput, StyleSheetParser};
#[cfg(feature = "sourcemap")]
use parcel_sourcemap::SourceMap;
use std::collections::{HashMap, HashSet};

pub use crate::parser::{ParserFlags, ParserOptions};
pub use crate::printer::PrinterOptions;
pub use crate::printer::PseudoClasses;

/// A CSS style sheet, representing a `.css` file or inline `<style>` element.
///
/// Style sheets can be parsed from a string, constructed from scratch,
/// or created using a [Bundler](super::bundler::Bundler). Then, they can be
/// minified and transformed for a set of target browsers, and serialied to a string.
///
/// # Example
///
/// ```
/// use lightningcss::stylesheet::{
///   StyleSheet, ParserOptions, MinifyOptions, PrinterOptions
/// };
///
/// // Parse a style sheet from a string.
/// let mut stylesheet = StyleSheet::parse(
///   r#"
///   .foo {
///     color: red;
///   }
///
///   .bar {
///     color: red;
///   }
///   "#,
///   ParserOptions::default()
/// ).unwrap();
///
/// // Minify the stylesheet.
/// stylesheet.minify(MinifyOptions::default()).unwrap();
///
/// // Serialize it to a string.
/// let res = stylesheet.to_css(PrinterOptions::default()).unwrap();
/// assert_eq!(res.code, ".foo, .bar {\n  color: red;\n}\n");
/// ```
#[derive(Debug)]
#[cfg_attr(
  feature = "serde",
  derive(serde::Serialize, serde::Deserialize),
  serde(rename_all = "camelCase")
)]
#[cfg_attr(
  feature = "jsonschema",
  derive(schemars::JsonSchema),
  schemars(rename = "StyleSheet", bound = "T: schemars::JsonSchema")
)]
pub struct StyleSheet<'i, 'o, T = DefaultAtRule> {
  /// A list of top-level rules within the style sheet.
  #[cfg_attr(feature = "serde", serde(borrow))]
  pub rules: CssRuleList<'i, T>,
  /// A list of file names for all source files included within the style sheet.
  /// Sources are referenced by index in the `loc` property of each rule.
  pub sources: Vec<String>,
  /// The source map URL extracted from the original style sheet.
  pub(crate) source_map_urls: Vec<Option<String>>,
  /// The license comments that appeared at the start of the file.
  pub license_comments: Vec<CowArcStr<'i>>,
  /// A list of content hashes for all source files included within the style sheet.
  /// This is only set if CSS modules are enabled and the pattern includes [content-hash].
  #[cfg_attr(feature = "serde", serde(skip))]
  pub(crate) content_hashes: Option<Vec<String>>,
  #[cfg_attr(feature = "serde", serde(skip))]
  /// The options the style sheet was originally parsed with.
  options: ParserOptions<'o, 'i>,
}

/// Options for the `minify` function of a [StyleSheet](StyleSheet)
/// or [StyleAttribute](StyleAttribute).
#[derive(Default)]
pub struct MinifyOptions {
  /// Targets to compile the CSS for.
  pub targets: Targets,
  /// A list of known unused symbols, including CSS class names,
  /// ids, and `@keyframe` names. The declarations of these will be removed.
  pub unused_symbols: HashSet<String>,
}

/// A result returned from `to_css`, including the serialize CSS
/// and other metadata depending on the input options.
#[derive(Debug)]
pub struct ToCssResult {
  /// Serialized CSS code.
  pub code: String,
  /// A map of CSS module exports, if the `css_modules` option was
  /// enabled during parsing.
  pub exports: Option<CssModuleExports>,
  /// A map of CSS module references, if the `css_modules` config
  /// had `dashed_idents` enabled.
  pub references: Option<CssModuleReferences>,
  /// A list of dependencies (e.g. `@import` or `url()`) found in
  /// the style sheet, if the `analyze_dependencies` option is enabled.
  pub dependencies: Option<Vec<Dependency>>,
}

impl<'i, 'o> StyleSheet<'i, 'o, DefaultAtRule> {
  /// Parse a style sheet from a string.
  pub fn parse(code: &'i str, options: ParserOptions<'o, 'i>) -> Result<Self, Error<ParserError<'i>>> {
    Self::parse_with(code, options, &mut DefaultAtRuleParser)
  }
}

impl<'i, 'o, T> StyleSheet<'i, 'o, T>
where
  T: ToCss + Clone,
{
  /// Creates a new style sheet with the given source filenames and rules.
  pub fn new(
    sources: Vec<String>,
    rules: CssRuleList<'i, T>,
    options: ParserOptions<'o, 'i>,
  ) -> StyleSheet<'i, 'o, T> {
    StyleSheet {
      sources,
      source_map_urls: Vec::new(),
      license_comments: Vec::new(),
      content_hashes: None,
      rules,
      options,
    }
  }

  /// Parse a style sheet from a string.
  pub fn parse_with<P: AtRuleParser<'i, AtRule = T>>(
    code: &'i str,
    mut options: ParserOptions<'o, 'i>,
    at_rule_parser: &mut P,
  ) -> Result<Self, Error<ParserError<'i>>> {
    let mut input = ParserInput::new(&code);
    let mut parser = Parser::new(&mut input);
    let mut license_comments = Vec::new();

    let mut content_hashes = None;
    if let Some(config) = &options.css_modules {
      if config.pattern.has_content_hash() {
        content_hashes = Some(vec![hash(
          &code,
          matches!(config.pattern.segments[0], crate::css_modules::Segment::ContentHash),
        )]);
      }
    }

    let mut state = parser.state();
    while let Ok(token) = parser.next_including_whitespace_and_comments() {
      match token {
        cssparser::Token::WhiteSpace(..) => {}
        cssparser::Token::Comment(comment) if comment.starts_with('!') => {
          license_comments.push((*comment).into());
        }
        cssparser::Token::Comment(comment) if comment.contains("cssmodules-pure-no-check") => {
          if let Some(css_modules) = &mut options.css_modules {
            css_modules.pure = false;
          }
        }
        _ => break,
      }
      state = parser.state();
    }
    parser.reset(&state);

    let mut rules = CssRuleList(vec![]);
    let mut rule_parser = TopLevelRuleParser::new(&mut options, at_rule_parser, &mut rules);
    let mut rule_list_parser = StyleSheetParser::new(&mut parser, &mut rule_parser);

    while let Some(rule) = rule_list_parser.next() {
      match rule {
        Ok(()) => {}
        Err((e, _)) => {
          let options = &mut rule_list_parser.parser.options;
          if options.error_recovery {
            options.warn(e);
            continue;
          }

          return Err(Error::from(e, options.filename.clone()));
        }
      }
    }

    Ok(StyleSheet {
      sources: vec![options.filename.clone()],
      source_map_urls: vec![parser.current_source_map_url().map(|s| s.to_owned())],
      content_hashes,
      rules,
      license_comments,
      options,
    })
  }

  /// Returns the source map URL for the source at the given index.
  pub fn source_map_url(&self, source_index: usize) -> Option<&String> {
    self.source_map_urls.get(source_index)?.as_ref()
  }

  /// Returns the inline source map associated with the source at the given index.
  #[cfg(feature = "sourcemap")]
  #[cfg_attr(docsrs, doc(cfg(feature = "sourcemap")))]
  pub fn source_map(&self, source_index: usize) -> Option<SourceMap> {
    SourceMap::from_data_url("/", self.source_map_url(source_index)?).ok()
  }

  /// Minify and transform the style sheet for the provided browser targets.
  pub fn minify(&mut self, options: MinifyOptions) -> Result<(), Error<MinifyErrorKind>> {
    let context = PropertyHandlerContext::new(options.targets, &options.unused_symbols);
    let mut handler = DeclarationHandler::default();
    let mut important_handler = DeclarationHandler::default();

    // @custom-media rules may be defined after they are referenced, but may only be defined at the top level
    // of a stylesheet. Do a pre-scan here and create a lookup table by name.
    let custom_media = if self.options.flags.contains(ParserFlags::CUSTOM_MEDIA)
      && should_compile!(options.targets, CustomMediaQueries)
    {
      let mut custom_media = HashMap::new();
      for rule in &self.rules.0 {
        if let CssRule::CustomMedia(rule) = rule {
          custom_media.insert(rule.name.0.clone(), rule.clone());
        }
      }
      Some(custom_media)
    } else {
      None
    };

    let mut ctx = MinifyContext {
      targets: TargetsWithSupportsScope::new(options.targets),
      handler: &mut handler,
      important_handler: &mut important_handler,
      handler_context: context,
      unused_symbols: &options.unused_symbols,
      custom_media,
      css_modules: self.options.css_modules.is_some(),
      pure_css_modules: self.options.css_modules.as_ref().map(|c| c.pure).unwrap_or_default(),
    };

    self.rules.minify(&mut ctx, false).map_err(|e| Error {
      kind: e.kind,
      loc: Some(ErrorLocation::new(
        e.loc,
        self.sources[e.loc.source_index as usize].clone(),
      )),
    })?;

    Ok(())
  }

  /// Serialize the style sheet to a CSS string.
  pub fn to_css(&self, options: PrinterOptions) -> Result<ToCssResult, Error<PrinterErrorKind>> {
    // Make sure we always have capacity > 0: https://github.com/napi-rs/napi-rs/issues/1124.
    let mut dest = String::with_capacity(1);
    let project_root = options.project_root.clone();
    let mut printer = Printer::new(&mut dest, options);

    #[cfg(feature = "sourcemap")]
    {
      printer.sources = Some(&self.sources);
    }

    #[cfg(feature = "sourcemap")]
    if printer.source_map.is_some() {
      printer.source_maps = self.sources.iter().enumerate().map(|(i, _)| self.source_map(i)).collect();
    }

    for comment in &self.license_comments {
      printer.write_str("/*")?;
      printer.write_str_with_newlines(comment)?;
      printer.write_str_with_newlines("*/\n")?;
    }

    if let Some(config) = &self.options.css_modules {
      let mut references = HashMap::new();
      printer.css_module = Some(CssModule::new(
        config,
        &self.sources,
        project_root,
        &mut references,
        &self.content_hashes,
      ));

      self.rules.to_css(&mut printer)?;
      printer.newline()?;

      Ok(ToCssResult {
        dependencies: printer.dependencies,
        exports: Some(std::mem::take(
          &mut printer.css_module.unwrap().exports_by_source_index[0],
        )),
        code: dest,
        references: Some(references),
      })
    } else {
      self.rules.to_css(&mut printer)?;
      printer.newline()?;

      Ok(ToCssResult {
        dependencies: printer.dependencies,
        code: dest,
        exports: None,
        references: None,
      })
    }
  }
}

#[cfg(feature = "visitor")]
#[cfg_attr(docsrs, doc(cfg(feature = "visitor")))]
impl<'i, 'o, T, V> Visit<'i, T, V> for StyleSheet<'i, 'o, T>
where
  T: Visit<'i, T, V>,
  V: ?Sized + Visitor<'i, T>,
{
  const CHILD_TYPES: VisitTypes = VisitTypes::all();

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

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

/// An inline style attribute, as in HTML or SVG.
///
/// Style attributes can be parsed from a string, minified and transformed
/// for a set of target browsers, and serialied to a string.
///
/// # Example
///
/// ```
/// use lightningcss::stylesheet::{
///   StyleAttribute, ParserOptions, MinifyOptions, PrinterOptions
/// };
///
/// // Parse a style sheet from a string.
/// let mut style = StyleAttribute::parse(
///   "color: yellow; font-family: 'Helvetica';",
///   ParserOptions::default()
/// ).unwrap();
///
/// // Minify the stylesheet.
/// style.minify(MinifyOptions::default());
///
/// // Serialize it to a string.
/// let res = style.to_css(PrinterOptions::default()).unwrap();
/// assert_eq!(res.code, "color: #ff0; font-family: Helvetica");
/// ```
#[cfg_attr(feature = "visitor", derive(Visit))]
#[cfg_attr(feature = "into_owned", derive(static_self::IntoOwned))]
pub struct StyleAttribute<'i> {
  /// The declarations in the style attribute.
  pub declarations: DeclarationBlock<'i>,
  #[cfg_attr(feature = "visitor", skip_visit)]
  sources: Vec<String>,
}

impl<'i> StyleAttribute<'i> {
  /// Parses a style attribute from a string.
  pub fn parse(
    code: &'i str,
    options: ParserOptions<'_, 'i>,
  ) -> Result<StyleAttribute<'i>, Error<ParserError<'i>>> {
    let mut input = ParserInput::new(&code);
    let mut parser = Parser::new(&mut input);
    Ok(StyleAttribute {
      declarations: DeclarationBlock::parse(&mut parser, &options).map_err(|e| Error::from(e, "".into()))?,
      sources: vec![options.filename],
    })
  }

  /// Minify and transform the style attribute for the provided browser targets.
  pub fn minify(&mut self, options: MinifyOptions) {
    let mut context = PropertyHandlerContext::new(options.targets, &options.unused_symbols);
    let mut handler = DeclarationHandler::default();
    let mut important_handler = DeclarationHandler::default();
    context.context = DeclarationContext::StyleAttribute;
    self.declarations.minify(&mut handler, &mut important_handler, &mut context);
  }

  /// Serializes the style attribute to a CSS string.
  pub fn to_css(&self, options: PrinterOptions) -> Result<ToCssResult, PrinterError> {
    #[cfg(feature = "sourcemap")]
    assert!(
      options.source_map.is_none(),
      "Source maps are not supported for style attributes"
    );

    // Make sure we always have capacity > 0: https://github.com/napi-rs/napi-rs/issues/1124.
    let mut dest = String::with_capacity(1);
    let mut printer = Printer::new(&mut dest, options);
    printer.sources = Some(&self.sources);

    self.declarations.to_css(&mut printer)?;

    Ok(ToCssResult {
      dependencies: printer.dependencies,
      code: dest,
      exports: None,
      references: None,
    })
  }
}
