require 'pathname'

module Sass::Tree
  # A static node representing a CSS rule.
  #
  # @see Sass::Tree
  class RuleNode < Node
    # The character used to include the parent selector
    PARENT = '&'

    # The CSS selector for this rule,
    # interspersed with {Sass::Script::Tree::Node}s
    # representing `#{}`-interpolation.
    # Any adjacent strings will be merged together.
    #
    # @return [Array<String, Sass::Script::Tree::Node>]
    attr_accessor :rule

    # The CSS selector for this rule, without any unresolved
    # interpolation but with parent references still intact. It's only
    # guaranteed to be set once {Tree::Visitors::Perform} has been
    # run, but it may be set before then for optimization reasons.
    #
    # @return [Selector::CommaSequence]
    attr_accessor :parsed_rules

    # The CSS selector for this rule, without any unresolved
    # interpolation or parent references. It's only set once
    # {Tree::Visitors::Perform} has been run.
    #
    # @return [Selector::CommaSequence]
    attr_accessor :resolved_rules

    # How deep this rule is indented
    # relative to a base-level rule.
    # This is only greater than 0 in the case that:
    #
    # * This node is in a CSS tree
    # * The style is :nested
    # * This is a child rule of another rule
    # * The parent rule has properties, and thus will be rendered
    #
    # @return [Integer]
    attr_accessor :tabs

    # The entire selector source range for this rule.
    # @return [Sass::Source::Range]
    attr_accessor :selector_source_range

    # Whether or not this rule is the last rule in a nested group.
    # This is only set in a CSS tree.
    #
    # @return [Boolean]
    attr_accessor :group_end

    # The stack trace.
    # This is only readable in a CSS tree as it is written during the perform step
    # and only when the :trace_selectors option is set.
    #
    # @return [String]
    attr_accessor :stack_trace

    # @param rule [Array<String, Sass::Script::Tree::Node>, Sass::Selector::CommaSequence]
    #   The CSS rule, either unparsed or parsed.
    # @param selector_source_range [Sass::Source::Range]
    def initialize(rule, selector_source_range = nil)
      if rule.is_a?(Sass::Selector::CommaSequence)
        @rule = [rule.to_s]
        @parsed_rules = rule
      else
        merged = Sass::Util.merge_adjacent_strings(rule)
        @rule = Sass::Util.strip_string_array(merged)
        try_to_parse_non_interpolated_rules
      end
      @selector_source_range = selector_source_range
      @tabs = 0
      super()
    end

    # If we've precached the parsed selector, set the line on it, too.
    def line=(line)
      @parsed_rules.line = line if @parsed_rules
      super
    end

    # If we've precached the parsed selector, set the filename on it, too.
    def filename=(filename)
      @parsed_rules.filename = filename if @parsed_rules
      super
    end

    # Compares the contents of two rules.
    #
    # @param other [Object] The object to compare with
    # @return [Boolean] Whether or not this node and the other object
    #   are the same
    def ==(other)
      self.class == other.class && rule == other.rule && super
    end

    # Adds another {RuleNode}'s rules to this one's.
    #
    # @param node [RuleNode] The other node
    def add_rules(node)
      @rule = Sass::Util.strip_string_array(
        Sass::Util.merge_adjacent_strings(@rule + ["\n"] + node.rule))
      try_to_parse_non_interpolated_rules
    end

    # @return [Boolean] Whether or not this rule is continued on the next line
    def continued?
      last = @rule.last
      last.is_a?(String) && last[-1] == ?,
    end

    # A hash that will be associated with this rule in the CSS document
    # if the {file:SASS_REFERENCE.md#debug_info-option `:debug_info` option} is enabled.
    # This data is used by e.g. [the FireSass Firebug
    # extension](https://addons.mozilla.org/en-US/firefox/addon/103988).
    #
    # @return [{#to_s => #to_s}]
    def debug_info
      {:filename => filename &&
         ("file://" + URI::DEFAULT_PARSER.escape(File.expand_path(filename))),
       :line => line}
    end

    # A rule node is invisible if it has only placeholder selectors.
    def invisible?
      resolved_rules.members.all? {|seq| seq.invisible?}
    end

    private

    def try_to_parse_non_interpolated_rules
      @parsed_rules = nil
      return unless @rule.all? {|t| t.is_a?(String)}

      # We don't use real filename/line info because we don't have it yet.
      # When we get it, we'll set it on the parsed rules if possible.
      parser = nil
      warnings = Sass::Util.silence_warnings do
        parser = Sass::SCSS::StaticParser.new(@rule.join.strip, nil, nil, 1)
        # rubocop:disable RescueModifier
        @parsed_rules = parser.parse_selector rescue nil
        # rubocop:enable RescueModifier

        $stderr.string
      end

      # If parsing produces a warning, throw away the result so we can parse
      # later with the real filename info.
      @parsed_rules = nil unless warnings.empty?
    end
  end
end
