// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

part of '../parser.dart';

// TODO(terry): Add optimizing phase to remove duplicated selectors in the same
//              selector group (e.g., .btn, .btn { color: red; }).  Also, look
//              at simplifying selectors expressions too (much harder).
// TODO(terry): Detect invalid directive usage.  All @imports must occur before
//              all rules other than @charset directive.  Any @import directive
//              after any non @charset or @import directive are ignored. e.g.,
//                  @import "a.css";
//                  div { color: red; }
//                  @import "b.css";
//              becomes:
//                  @import "a.css";
//                  div { color: red; }
// <http://www.w3.org/TR/css3-syntax/#at-rules>

/// Analysis phase will validate/fixup any new CSS feature or any Sass style
/// feature.
class Analyzer {
  final List<StyleSheet> _styleSheets;
  final Messages _messages;

  Analyzer(this._styleSheets, this._messages);

  // TODO(terry): Currently each feature walks the AST each time.  Once we have
  //               our complete feature set consider benchmarking the cost and
  //               possibly combine in one walk.
  void run() {
    // Expand top-level @include.
    TopLevelIncludes.expand(_messages, _styleSheets);

    // Expand @include in declarations.
    DeclarationIncludes.expand(_messages, _styleSheets);

    // Remove all @mixin and @include
    for (var styleSheet in _styleSheets) {
      MixinsAndIncludes.remove(styleSheet);
    }

    // Expand any nested selectors using selector descendant combinator to
    // signal CSS inheritance notation.
    for (var styleSheet in _styleSheets) {
      ExpandNestedSelectors()
        ..visitStyleSheet(styleSheet)
        ..flatten(styleSheet);
    }

    // Expand any @extend.
    for (var styleSheet in _styleSheets) {
      var allExtends = AllExtends()..visitStyleSheet(styleSheet);
      InheritExtends(_messages, allExtends).visitStyleSheet(styleSheet);
    }
  }
}

/// Traverse all rulesets looking for nested ones.  If a ruleset is in a
/// declaration group (implies nested selector) then generate new ruleset(s) at
/// level 0 of CSS using selector inheritance syntax (flattens the nesting).
///
/// How the AST works for a rule [RuleSet] and nested rules.  First of all a
/// CSS rule [RuleSet] consist of a selector and a declaration e.g.,
///
///     selector {
///       declaration
///     }
///
/// AST structure of a [RuleSet] is:
///
///     RuleSet
///        SelectorGroup
///          List<Selector>
///             List<SimpleSelectorSequence>
///               Combinator      // +, >, ~, DESCENDENT, or NONE
///               SimpleSelector  // class, id, element, namespace, attribute
///         DeclarationGroup
///           List                // Declaration or RuleSet
///
/// For the simple rule:
///
///     div + span { color: red; }
///
/// the AST [RuleSet] is:
///
///     RuleSet
///        SelectorGroup
///          List<Selector>
///           [0]
///             List<SimpleSelectorSequence>
///               [0] Combinator = COMBINATOR_NONE
///                   ElementSelector (name = div)
///               [1] Combinator = COMBINATOR_PLUS
///                   ElementSelector (name = span)
///         DeclarationGroup
///           List                // Declarations or RuleSets
///             [0]
///               Declaration (property = color, expression = red)
///
/// Usually a SelectorGroup contains 1 Selector.  Consider the selectors:
///
///     div { color: red; }
///     a { color: red; }
///
/// are equivalent to
///
///     div, a { color : red; }
///
/// In the above the RuleSet would have a SelectorGroup with 2 selectors e.g.,
///
///     RuleSet
///        SelectorGroup
///          List<Selector>
///           [0]
///             List<SimpleSelectorSequence>
///               [0] Combinator = COMBINATOR_NONE
///                   ElementSelector (name = div)
///           [1]
///             List<SimpleSelectorSequence>
///               [0] Combinator = COMBINATOR_NONE
///                   ElementSelector (name = a)
///         DeclarationGroup
///           List                // Declarations or RuleSets
///             [0]
///               Declaration (property = color, expression = red)
///
/// For a nested rule e.g.,
///
///     div {
///       color : blue;
///       a { color : red; }
///     }
///
/// Would map to the follow CSS rules:
///
///     div { color: blue; }
///     div a { color: red; }
///
/// The AST for the former nested rule is:
///
///     RuleSet
///        SelectorGroup
///          List<Selector>
///           [0]
///             List<SimpleSelectorSequence>
///               [0] Combinator = COMBINATOR_NONE
///                   ElementSelector (name = div)
///         DeclarationGroup
///           List                // Declarations or RuleSets
///             [0]
///               Declaration (property = color, expression = blue)
///             [1]
///               RuleSet
///                 SelectorGroup
///                   List<Selector>
///                     [0]
///                       List<SimpleSelectorSequence>
///                         [0] Combinator = COMBINATOR_NONE
///                             ElementSelector (name = a)
///                 DeclarationGroup
///                   List                // Declarations or RuleSets
///                     [0]
///                       Declaration (property = color, expression = red)
///
/// Nested rules is a terse mechanism to describe CSS inheritance.  The analyzer
/// will flatten and expand the nested rules to it's flatten structure.  Using
/// the all parent [RuleSets] (selector expressions) and applying each nested
/// [RuleSet] to the list of [Selectors] in a [SelectorGroup].
///
/// Then result is a style sheet where all nested rules have been flatten and
/// expanded.
class ExpandNestedSelectors extends Visitor {
  /// Parent [RuleSet] if a nested rule otherwise `null`.
  RuleSet? _parentRuleSet;

  /// Top-most rule if nested rules.
  SelectorGroup? _topLevelSelectorGroup;

  /// SelectorGroup at each nesting level.
  SelectorGroup? _nestedSelectorGroup;

  /// Declaration (sans the nested selectors).
  DeclarationGroup? _flatDeclarationGroup;

  /// Each nested selector get's a flatten RuleSet.
  List<RuleSet> _expandedRuleSets = [];

  /// Maping of a nested rule set to the fully expanded list of RuleSet(s).
  final _expansions = <RuleSet, List<RuleSet>>{};

  @override
  void visitRuleSet(RuleSet node) {
    final oldParent = _parentRuleSet;

    var oldNestedSelectorGroups = _nestedSelectorGroup;

    if (_nestedSelectorGroup == null) {
      // Create top-level selector (may have nested rules).
      final newSelectors = node.selectorGroup!.selectors.toList();
      _topLevelSelectorGroup = SelectorGroup(newSelectors, node.span);
      _nestedSelectorGroup = _topLevelSelectorGroup;
    } else {
      // Generate new selector groups from the nested rules.
      _nestedSelectorGroup = _mergeToFlatten(node);
    }

    _parentRuleSet = node;

    super.visitRuleSet(node);

    _parentRuleSet = oldParent;

    // Remove nested rules; they're all flatten and in the _expandedRuleSets.
    node.declarationGroup.declarations
        .removeWhere((declaration) => declaration is RuleSet);

    _nestedSelectorGroup = oldNestedSelectorGroups;

    // If any expandedRuleSets and we're back at the top-level rule set then
    // there were nested rule set(s).
    if (_parentRuleSet == null) {
      if (_expandedRuleSets.isNotEmpty) {
        // Remember ruleset to replace with these flattened rulesets.
        _expansions[node] = _expandedRuleSets;
        _expandedRuleSets = [];
      }
      assert(_flatDeclarationGroup == null);
      assert(_nestedSelectorGroup == null);
    }
  }

  /// Build up the list of all inherited sequences from the parent selector
  /// [node] is the current nested selector and it's parent is the last entry in
  /// the [_nestedSelectorGroup].
  SelectorGroup _mergeToFlatten(RuleSet node) {
    // Create a new SelectorGroup for this nesting level.
    var nestedSelectors = _nestedSelectorGroup!.selectors;
    var selectors = node.selectorGroup!.selectors;

    // Create a merged set of previous parent selectors and current selectors.
    var newSelectors = <Selector>[];
    for (var selector in selectors) {
      for (var nestedSelector in nestedSelectors) {
        var seq = _mergeNestedSelector(nestedSelector.simpleSelectorSequences,
            selector.simpleSelectorSequences);
        newSelectors.add(Selector(seq, node.span));
      }
    }

    return SelectorGroup(newSelectors, node.span);
  }

  /// Merge the nested selector sequences [current] to the [parent] sequences or
  /// substitute any & with the parent selector.
  List<SimpleSelectorSequence> _mergeNestedSelector(
      List<SimpleSelectorSequence> parent,
      List<SimpleSelectorSequence> current) {
    // If any & operator then the parent selector will be substituted otherwise
    // the parent selector is pre-pended to the current selector.
    var hasThis = current.any((s) => s.simpleSelector.isThis);

    var newSequence = <SimpleSelectorSequence>[];

    if (!hasThis) {
      // If no & in the sector group then prefix with the parent selector.
      newSequence.addAll(parent);
      newSequence.addAll(_convertToDescendentSequence(current));
    } else {
      for (var sequence in current) {
        if (sequence.simpleSelector.isThis) {
          // Substitute the & with the parent selector and only use a combinator
          // descendant if & is prefix by a sequence with an empty name e.g.,
          // "... + &", "&", "... ~ &", etc.
          var hasPrefix = newSequence.isNotEmpty &&
              newSequence.last.simpleSelector.name.isNotEmpty;
          newSequence.addAll(
              hasPrefix ? _convertToDescendentSequence(parent) : parent);
        } else {
          newSequence.add(sequence);
        }
      }
    }

    return newSequence;
  }

  /// Return selector sequences with first sequence combinator being a
  /// descendant.  Used for nested selectors when the parent selector needs to
  /// be prefixed to a nested selector or to substitute the this (&) with the
  /// parent selector.
  List<SimpleSelectorSequence> _convertToDescendentSequence(
      List<SimpleSelectorSequence> sequences) {
    if (sequences.isEmpty) return sequences;

    var newSequences = <SimpleSelectorSequence>[];
    var first = sequences.first;
    newSequences.add(SimpleSelectorSequence(
        first.simpleSelector, first.span, TokenKind.COMBINATOR_DESCENDANT));
    newSequences.addAll(sequences.skip(1));

    return newSequences;
  }

  @override
  void visitDeclarationGroup(DeclarationGroup node) {
    var span = node.span;

    var currentGroup = DeclarationGroup([], span);

    var oldGroup = _flatDeclarationGroup;
    _flatDeclarationGroup = currentGroup;

    var expandedLength = _expandedRuleSets.length;

    super.visitDeclarationGroup(node);

    // We're done with the group.
    _flatDeclarationGroup = oldGroup;

    // No nested rule to process it's a top-level rule.
    if (_nestedSelectorGroup == _topLevelSelectorGroup) return;

    // If flatten selector's declaration is empty skip this selector, no need
    // to emit an empty nested selector.
    if (currentGroup.declarations.isEmpty) return;

    var selectorGroup = _nestedSelectorGroup;

    // Build new rule set from the nested selectors and declarations.
    var newRuleSet = RuleSet(selectorGroup, currentGroup, span);

    // Place in order so outer-most rule is first.
    if (expandedLength == _expandedRuleSets.length) {
      _expandedRuleSets.add(newRuleSet);
    } else {
      _expandedRuleSets.insert(expandedLength, newRuleSet);
    }
  }

  // Record all declarations in a nested selector (Declaration, VarDefinition
  // and MarginGroup) but not the nested rule in the Declaration.

  @override
  void visitDeclaration(Declaration node) {
    if (_parentRuleSet != null) {
      _flatDeclarationGroup!.declarations.add(node);
    }
    super.visitDeclaration(node);
  }

  @override
  void visitVarDefinition(VarDefinition node) {
    if (_parentRuleSet != null) {
      _flatDeclarationGroup!.declarations.add(node);
    }
    super.visitVarDefinition(node);
  }

  @override
  void visitExtendDeclaration(ExtendDeclaration node) {
    if (_parentRuleSet != null) {
      _flatDeclarationGroup!.declarations.add(node);
    }
    super.visitExtendDeclaration(node);
  }

  @override
  void visitMarginGroup(MarginGroup node) {
    if (_parentRuleSet != null) {
      _flatDeclarationGroup!.declarations.add(node);
    }
    super.visitMarginGroup(node);
  }

  /// Replace the rule set that contains nested rules with the flatten rule
  /// sets.
  void flatten(StyleSheet styleSheet) {
    // TODO(terry): Iterate over topLevels instead of _expansions it's already
    //              a map (this maybe quadratic).
    _expansions.forEach((RuleSet ruleSet, List<RuleSet> newRules) {
      var index = styleSheet.topLevels.indexOf(ruleSet);
      if (index == -1) {
        // Check any @media directives for nested rules and replace them.
        var found = _MediaRulesReplacer.replace(styleSheet, ruleSet, newRules);
        assert(found);
      } else {
        styleSheet.topLevels.insertAll(index + 1, newRules);
      }
    });
    _expansions.clear();
  }
}

class _MediaRulesReplacer extends Visitor {
  final RuleSet _ruleSet;
  final List<RuleSet> _newRules;
  bool _foundAndReplaced = false;

  /// Look for the [ruleSet] inside of an @media directive; if found then
  /// replace with the [newRules].  If [ruleSet] is found and replaced return
  /// true.
  static bool replace(
      StyleSheet styleSheet, RuleSet ruleSet, List<RuleSet> newRules) {
    var visitor = _MediaRulesReplacer(ruleSet, newRules);
    visitor.visitStyleSheet(styleSheet);
    return visitor._foundAndReplaced;
  }

  _MediaRulesReplacer(this._ruleSet, this._newRules);

  @override
  void visitMediaDirective(MediaDirective node) {
    var index = node.rules.indexOf(_ruleSet);
    if (index != -1) {
      node.rules.insertAll(index + 1, _newRules);
      _foundAndReplaced = true;
    }
  }
}

/// Expand all @include at the top-level the ruleset(s) associated with the
/// mixin.
class TopLevelIncludes extends Visitor {
  StyleSheet? _styleSheet;
  final Messages _messages;

  /// Map of variable name key to it's definition.
  final map = <String, MixinDefinition>{};
  MixinDefinition? currDef;

  static void expand(Messages messages, List<StyleSheet> styleSheets) {
    TopLevelIncludes(messages, styleSheets);
  }

  bool _anyRulesets(MixinRulesetDirective def) =>
      def.rulesets.any((rule) => rule is RuleSet);

  TopLevelIncludes(this._messages, List<StyleSheet> styleSheets) {
    for (var styleSheet in styleSheets) {
      visitTree(styleSheet);
    }
  }

  @override
  void visitStyleSheet(StyleSheet ss) {
    _styleSheet = ss;
    super.visitStyleSheet(ss);
    _styleSheet = null;
  }

  @override
  void visitIncludeDirective(IncludeDirective node) {
    final currDef = this.currDef;
    if (map.containsKey(node.name)) {
      var mixinDef = map[node.name];
      if (mixinDef is MixinRulesetDirective) {
        _TopLevelIncludeReplacer.replace(_styleSheet!, node, mixinDef.rulesets);
      } else if (currDef is MixinRulesetDirective && _anyRulesets(currDef)) {
        final mixinRuleset = currDef;
        var index = mixinRuleset.rulesets.indexOf(node);
        mixinRuleset.rulesets.removeAt(index);
        _messages.warning(
            'Using declaration mixin ${node.name} as top-level mixin',
            node.span);
      }
    } else {
      if (currDef is MixinRulesetDirective) {
        var rulesetDirect = currDef;
        rulesetDirect.rulesets.removeWhere((entry) {
          if (entry == node) {
            _messages.warning('Undefined mixin ${node.name}', node.span);
            return true;
          }
          return false;
        });
      }
    }
    super.visitIncludeDirective(node);
  }

  @override
  void visitMixinRulesetDirective(MixinRulesetDirective node) {
    currDef = node;

    super.visitMixinRulesetDirective(node);

    // Replace with latest top-level mixin definition.
    map[node.name] = node;
    currDef = null;
  }

  @override
  void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
    currDef = node;

    super.visitMixinDeclarationDirective(node);

    // Replace with latest mixin definition.
    map[node.name] = node;
    currDef = null;
  }
}

/// @include as a top-level with ruleset(s).
class _TopLevelIncludeReplacer extends Visitor {
  final IncludeDirective _include;
  final List<TreeNode> _newRules;

  /// Look for the [ruleSet] inside of an @media directive; if found then
  /// replace with the [newRules].  If [ruleSet] is found and replaced return
  /// true.
  static void replace(StyleSheet styleSheet, IncludeDirective include,
      List<TreeNode> newRules) {
    _TopLevelIncludeReplacer(include, newRules).visitStyleSheet(styleSheet);
  }

  _TopLevelIncludeReplacer(this._include, this._newRules);

  @override
  void visitStyleSheet(StyleSheet node) {
    var index = node.topLevels.indexOf(_include);
    if (index != -1) {
      node.topLevels.insertAll(index + 1, _newRules);
      node.topLevels.replaceRange(index, index + 1, [NoOp()]);
    }
    super.visitStyleSheet(node);
  }

  @override
  void visitMixinRulesetDirective(MixinRulesetDirective node) {
    var index = node.rulesets.indexOf(_include);
    if (index != -1) {
      node.rulesets.insertAll(index + 1, _newRules);
      // Only the resolve the @include once.
      node.rulesets.replaceRange(index, index + 1, [NoOp()]);
    }
    super.visitMixinRulesetDirective(node);
  }
}

/// Utility function to match an include to a list of either Declarations or
/// RuleSets, depending on type of mixin (ruleset or declaration).  The include
/// can be an include in a declaration or an include directive (top-level).
int _findInclude(List<Object> list, TreeNode node) {
  final matchNode = (node is IncludeMixinAtDeclaration)
      ? node.include
      : node as IncludeDirective;

  var index = 0;
  for (var item in list) {
    var includeNode = (item is IncludeMixinAtDeclaration) ? item.include : item;
    if (includeNode == matchNode) return index;
    index++;
  }
  return -1;
}

/// Stamp out a mixin with the defined args substituted with the user's
/// parameters.
class CallMixin extends Visitor {
  final MixinDefinition mixinDef;
  List<TreeNode>? _definedArgs;
  Expressions? _currExpressions;
  int _currIndex = -1;

  final varUsages = <String, Map<Expressions, Set<int>>>{};

  /// Only var defs with more than one expression (comma separated).
  final Map<String, VarDefinition>? varDefs;

  CallMixin(this.mixinDef, [this.varDefs]) {
    if (mixinDef is MixinRulesetDirective) {
      visitMixinRulesetDirective(mixinDef as MixinRulesetDirective);
    } else {
      visitMixinDeclarationDirective(mixinDef as MixinDeclarationDirective);
    }
  }

  /// Given a mixin's defined arguments return a cloned mixin definition that
  /// has replaced all defined arguments with user's supplied VarUsages.
  MixinDefinition transform(List<List<Expression>> callArgs) {
    // TODO(terry): Handle default arguments and varArgs.
    // Transform mixin with callArgs.
    for (var index = 0; index < _definedArgs!.length; index++) {
      var definedArg = _definedArgs![index];
      VarDefinition? varDef;
      if (definedArg is VarDefinition) {
        varDef = definedArg;
      } else if (definedArg is VarDefinitionDirective) {
        var varDirective = definedArg;
        varDef = varDirective.def;
      }
      var callArg = callArgs[index];

      // Is callArg a var definition with multi-args (expressions > 1).
      var defArgs = _varDefsAsCallArgs(callArg);
      if (defArgs.isNotEmpty) {
        // Replace call args with the var def parameters.
        callArgs.insertAll(index, defArgs);
        callArgs.removeAt(index + defArgs.length);
        callArg = callArgs[index];
      }

      var expressions = varUsages[varDef!.definedName];
      expressions!.forEach((k, v) {
        for (var usagesIndex in v) {
          k.expressions.replaceRange(usagesIndex, usagesIndex + 1, callArg);
        }
      });
    }

    // Clone the mixin
    return mixinDef.clone();
  }

  /// Rip apart var def with multiple parameters.
  List<List<Expression>> _varDefsAsCallArgs(List<Expression> callArg) {
    var defArgs = <List<Expression>>[];
    var firstCallArg = callArg[0];
    if (firstCallArg is VarUsage) {
      var varDef = varDefs![firstCallArg.name];
      var expressions = (varDef!.expression as Expressions).expressions;
      assert(expressions.length > 1);
      for (var expr in expressions) {
        if (expr is! OperatorComma) {
          defArgs.add([expr]);
        }
      }
    }
    return defArgs;
  }

  @override
  void visitExpressions(Expressions node) {
    var oldExpressions = _currExpressions;
    var oldIndex = _currIndex;

    _currExpressions = node;
    for (_currIndex = 0; _currIndex < node.expressions.length; _currIndex++) {
      node.expressions[_currIndex].visit(this);
    }

    _currIndex = oldIndex;
    _currExpressions = oldExpressions;
  }

  void _addExpression(Map<Expressions, Set<int>> expressions) {
    var indexSet = <int>{};
    indexSet.add(_currIndex);
    expressions[_currExpressions!] = indexSet;
  }

  @override
  void visitVarUsage(VarUsage node) {
    assert(_currIndex != -1);
    assert(_currExpressions != null);
    if (varUsages.containsKey(node.name)) {
      var expressions = varUsages[node.name];
      var allIndexes = expressions![_currExpressions];
      if (allIndexes == null) {
        _addExpression(expressions);
      } else {
        allIndexes.add(_currIndex);
      }
    } else {
      var newExpressions = <Expressions, Set<int>>{};
      _addExpression(newExpressions);
      varUsages[node.name] = newExpressions;
    }
    super.visitVarUsage(node);
  }

  @override
  void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
    _definedArgs = node.definedArgs;
    super.visitMixinDeclarationDirective(node);
  }

  @override
  void visitMixinRulesetDirective(MixinRulesetDirective node) {
    _definedArgs = node.definedArgs;
    super.visitMixinRulesetDirective(node);
  }
}

/// Expand all @include inside of a declaration associated with a mixin.
class DeclarationIncludes extends Visitor {
  StyleSheet? _styleSheet;
  final Messages _messages;

  /// Map of variable name key to it's definition.
  final Map<String, MixinDefinition> map = <String, MixinDefinition>{};

  /// Cache of mixin called with parameters.
  final Map<String, CallMixin> callMap = <String, CallMixin>{};
  MixinDefinition? currDef;
  DeclarationGroup? currDeclGroup;

  /// Var definitions with more than 1 expression.
  final varDefs = <String, VarDefinition>{};

  static void expand(Messages messages, List<StyleSheet> styleSheets) {
    DeclarationIncludes(messages, styleSheets);
  }

  DeclarationIncludes(this._messages, List<StyleSheet> styleSheets) {
    for (var styleSheet in styleSheets) {
      visitTree(styleSheet);
    }
  }

  bool _allIncludes(List<TreeNode> rulesets) =>
      rulesets.every((rule) => rule is IncludeDirective || rule is NoOp);

  CallMixin _createCallDeclMixin(MixinDefinition mixinDef) =>
      callMap[mixinDef.name] ??= CallMixin(mixinDef, varDefs);

  @override
  void visitStyleSheet(StyleSheet ss) {
    _styleSheet = ss;
    super.visitStyleSheet(ss);
    _styleSheet = null;
  }

  @override
  void visitDeclarationGroup(DeclarationGroup node) {
    currDeclGroup = node;
    super.visitDeclarationGroup(node);
    currDeclGroup = null;
  }

  @override
  void visitIncludeMixinAtDeclaration(IncludeMixinAtDeclaration node) {
    if (map.containsKey(node.include.name)) {
      var mixinDef = map[node.include.name];

      // Fix up any mixin that is really a Declaration but has includes.
      if (mixinDef is MixinRulesetDirective) {
        if (!_allIncludes(mixinDef.rulesets) && currDeclGroup != null) {
          var index = _findInclude(currDeclGroup!.declarations, node);
          if (index != -1) {
            currDeclGroup!.declarations
                .replaceRange(index, index + 1, [NoOp()]);
          }
          _messages.warning(
              'Using top-level mixin ${node.include.name} as a declaration',
              node.span);
        } else {
          // We're a list of @include(s) inside of a mixin ruleset - convert
          // to a list of IncludeMixinAtDeclaration(s).
          var origRulesets = mixinDef.rulesets;
          var rulesets = <Declaration>[];
          if (origRulesets.every((ruleset) => ruleset is IncludeDirective)) {
            for (var ruleset in origRulesets) {
              rulesets.add(IncludeMixinAtDeclaration(
                  ruleset as IncludeDirective, ruleset.span));
            }
            _IncludeReplacer.replace(_styleSheet!, node, rulesets);
          }
        }
      }

      if (mixinDef!.definedArgs.isNotEmpty && node.include.args.isNotEmpty) {
        var callMixin = _createCallDeclMixin(mixinDef);
        mixinDef = callMixin.transform(node.include.args);
      }

      if (mixinDef is MixinDeclarationDirective) {
        _IncludeReplacer.replace(
            _styleSheet!, node, mixinDef.declarations.declarations);
      }
    } else {
      _messages.warning('Undefined mixin ${node.include.name}', node.span);
    }

    super.visitIncludeMixinAtDeclaration(node);
  }

  @override
  void visitIncludeDirective(IncludeDirective node) {
    if (map.containsKey(node.name)) {
      var mixinDef = map[node.name];
      if (currDef is MixinDeclarationDirective &&
          mixinDef is MixinDeclarationDirective) {
        _IncludeReplacer.replace(
            _styleSheet!, node, mixinDef.declarations.declarations);
      } else if (currDef is MixinDeclarationDirective) {
        var decls =
            (currDef as MixinDeclarationDirective).declarations.declarations;
        var index = _findInclude(decls, node);
        if (index != -1) {
          decls.replaceRange(index, index + 1, [NoOp()]);
        }
      }
    }

    super.visitIncludeDirective(node);
  }

  @override
  void visitMixinRulesetDirective(MixinRulesetDirective node) {
    currDef = node;

    super.visitMixinRulesetDirective(node);

    // Replace with latest top-level mixin definition.
    map[node.name] = node;
    currDef = null;
  }

  @override
  void visitMixinDeclarationDirective(MixinDeclarationDirective node) {
    currDef = node;

    super.visitMixinDeclarationDirective(node);

    // Replace with latest mixin definition.
    map[node.name] = node;
    currDef = null;
  }

  @override
  void visitVarDefinition(VarDefinition node) {
    // Only record var definitions that have multiple expressions (comma
    // separated for mixin parameter substitution.
    var exprs = (node.expression as Expressions).expressions;
    if (exprs.length > 1) {
      varDefs[node.definedName] = node;
    }
    super.visitVarDefinition(node);
  }

  @override
  void visitVarDefinitionDirective(VarDefinitionDirective node) {
    visitVarDefinition(node.def);
  }
}

/// @include as a top-level with ruleset(s).
class _IncludeReplacer extends Visitor {
  final TreeNode _include;
  final List<TreeNode> _newDeclarations;

  /// Look for the [ruleSet] inside of a @media directive; if found then replace
  /// with the [newRules].
  static void replace(
      StyleSheet ss, TreeNode include, List<TreeNode> newDeclarations) {
    var visitor = _IncludeReplacer(include, newDeclarations);
    visitor.visitStyleSheet(ss);
  }

  _IncludeReplacer(this._include, this._newDeclarations);

  @override
  void visitDeclarationGroup(DeclarationGroup node) {
    var index = _findInclude(node.declarations, _include);
    if (index != -1) {
      node.declarations.insertAll(index + 1, _newDeclarations);
      // Change @include to NoOp so it's processed only once.
      node.declarations.replaceRange(index, index + 1, [NoOp()]);
    }
    super.visitDeclarationGroup(node);
  }
}

/// Remove all @mixin and @include and any NoOp used as placeholder for
/// @include.
class MixinsAndIncludes extends Visitor {
  static void remove(StyleSheet styleSheet) {
    MixinsAndIncludes().visitStyleSheet(styleSheet);
  }

  bool _nodesToRemove(Object node) =>
      node is IncludeDirective || node is MixinDefinition || node is NoOp;

  @override
  void visitStyleSheet(StyleSheet ss) {
    var index = ss.topLevels.length;
    while (--index >= 0) {
      if (_nodesToRemove(ss.topLevels[index])) {
        ss.topLevels.removeAt(index);
      }
    }
    super.visitStyleSheet(ss);
  }

  @override
  void visitDeclarationGroup(DeclarationGroup node) {
    var index = node.declarations.length;
    while (--index >= 0) {
      if (_nodesToRemove(node.declarations[index])) {
        node.declarations.removeAt(index);
      }
    }
    super.visitDeclarationGroup(node);
  }
}

/// Find all @extend to create inheritance.
class AllExtends extends Visitor {
  final inherits = <String, List<SelectorGroup>>{};

  SelectorGroup? _currSelectorGroup;
  int? _currDeclIndex;
  final _extendsToRemove = <int>[];

  @override
  void visitRuleSet(RuleSet node) {
    var oldSelectorGroup = _currSelectorGroup;
    _currSelectorGroup = node.selectorGroup;

    super.visitRuleSet(node);

    _currSelectorGroup = oldSelectorGroup;
  }

  @override
  void visitExtendDeclaration(ExtendDeclaration node) {
    var inheritName = '';
    for (var selector in node.selectors) {
      inheritName += selector.toString();
    }
    if (inherits.containsKey(inheritName)) {
      inherits[inheritName]!.add(_currSelectorGroup!);
    } else {
      inherits[inheritName] = [_currSelectorGroup!];
    }

    // Remove this @extend
    _extendsToRemove.add(_currDeclIndex!);

    super.visitExtendDeclaration(node);
  }

  @override
  void visitDeclarationGroup(DeclarationGroup node) {
    var oldDeclIndex = _currDeclIndex;

    var decls = node.declarations;
    for (_currDeclIndex = 0;
        _currDeclIndex! < decls.length;
        _currDeclIndex = _currDeclIndex! + 1) {
      decls[_currDeclIndex!].visit(this);
    }

    if (_extendsToRemove.isNotEmpty) {
      var removeTotal = _extendsToRemove.length - 1;
      for (var index = removeTotal; index >= 0; index--) {
        decls.removeAt(_extendsToRemove[index]);
      }
      _extendsToRemove.clear();
    }

    _currDeclIndex = oldDeclIndex;
  }
}

// TODO(terry): Need to handle merging selector sequences
// TODO(terry): Need to handle @extend-Only selectors.
// TODO(terry): Need to handle !optional glag.
/// Changes any selector that matches @extend.
class InheritExtends extends Visitor {
  final AllExtends _allExtends;

  InheritExtends(Messages messages, this._allExtends);

  @override
  void visitSelectorGroup(SelectorGroup node) {
    for (var selectorsIndex = 0;
        selectorsIndex < node.selectors.length;
        selectorsIndex++) {
      var selectors = node.selectors[selectorsIndex];
      var isLastNone = false;
      var selectorName = '';
      for (var index = 0;
          index < selectors.simpleSelectorSequences.length;
          index++) {
        var simpleSeq = selectors.simpleSelectorSequences[index];
        var namePart = simpleSeq.simpleSelector.toString();
        selectorName = isLastNone ? (selectorName + namePart) : namePart;
        var matches = _allExtends.inherits[selectorName];
        if (matches != null) {
          for (var match in matches) {
            // Create a new group.
            var newSelectors = selectors.clone();
            var newSeq = match.selectors[0].clone();
            if (isLastNone) {
              // Add the inherited selector.
              node.selectors.add(newSeq);
            } else {
              // Replace the selector sequence to the left of the pseudo class
              // or pseudo element.

              // Make new selector seq combinator the same as the original.
              var orgCombinator =
                  newSelectors.simpleSelectorSequences[index].combinator;
              newSeq.simpleSelectorSequences[0].combinator = orgCombinator;

              newSelectors.simpleSelectorSequences.replaceRange(
                  index, index + 1, newSeq.simpleSelectorSequences);
              node.selectors.add(newSelectors);
            }
            isLastNone = false;
          }
        } else {
          isLastNone = simpleSeq.isCombinatorNone;
        }
      }
    }
    super.visitSelectorGroup(node);
  }
}
