class RuboCop::Cop::Style::MagicCommentFormat


# frozen-string-literal: TRUE
# good
# frozen-string-literal: true
# bad
@example ValueCapitalization: uppercase
# frozen-string-literal: TRUE
# good
# frozen-string-literal: TRUE
# bad
# when a value is not given, any capitalization is accepted
@example ValueCapitalization: lowercase
# frozen-string-literal: TRUE
# good
# frozen-string-literal: true
# good
# any capitalization is accepted
@example ValueCapitalization: nil (default)
# FROZEN-STRING-LITERAL: true
# good
# frozen-string-literal: true
# good
# any capitalization is accepted
@example DirectiveCapitalization: nil
# FROZEN-STRING-LITERAL: true
# good
# frozen-string-literal: true
# bad
@example DirectiveCapitalization: uppercase
# frozen-string-literal: true
# good
# FROZEN-STRING-LITERAL: true
# bad
@example DirectiveCapitalization: lowercase (default)
end
# …
module Baz
# frozen-string-literal: true
# good
end
# …
module Baz
# frozen_string_literal: true
# bad
# comment is written in kebab case. (Words separated by hyphens)
# The ‘kebab_case` style will enforce that the frozen string literal
@example EnforcedStyle: kebab_case
end
# …
module Bar
# frozen_string_literal: false
# good
end
# …
module Bar
# frozen-string-literal: true
# bad
# comment is written in snake case. (Words separated by underscores)
# The `snake_case` style will enforce that the frozen string literal
@example EnforcedStyle: snake_case (default)
NOTE: If one of these configuration is set to nil, any capitalization is allowed.
`ValueCapitalization` configuration keys.
Required capitalization can be set with the `DirectiveCapitalization` and
both magic comment directives and values.
Looks for discrepancies in separators (`-` vs `_`) and capitalization for
Ensures magic comments are written consistently throughout your code base.

def correct_separator

def correct_separator
  style == :snake_case ? SNAKE_SEPARATOR : KEBAB_SEPARATOR
end

def directive_capitalization

def directive_capitalization
  cop_config['DirectiveCapitalization']&.to_sym.tap do |style|
    unless valid_capitalization?(style)
      raise "Unknown `DirectiveCapitalization` #{style} selected!"
    end
  end
end

def directive_offends?(directive)

def directive_offends?(directive)
  incorrect_separator?(directive.source) ||
    wrong_capitalization?(directive.source, directive_capitalization)
end

def expected_style

def expected_style
  [directive_capitalization, style].compact.join(' ').gsub(/_?case\b/, '')
end

def find_issues(comment)

def find_issues(comment)
  issues = { directives: [], values: [] }
  comment.directives.each do |directive|
    issues[:directives] << directive if directive_offends?(directive)
  end
  comment.values.each do |value| # rubocop:disable Style/HashEachMethods
    issues[:values] << value if wrong_capitalization?(value.source, value_capitalization)
  end
  issues
end

def fix_directives(issues)

def fix_directives(issues)
  return if issues.empty?
  msg = format(MSG, style: expected_style)
  issues.each do |directive|
    add_offense(directive, message: msg) do |corrector|
      replacement = replace_separator(replace_capitalization(directive.source,
                                                             directive_capitalization))
      corrector.replace(directive, replacement)
    end
  end
end

def fix_values(issues)

def fix_values(issues)
  return if issues.empty?
  msg = format(MSG_VALUE, case: value_capitalization)
  issues.each do |value|
    add_offense(value, message: msg) do |corrector|
      corrector.replace(value, replace_capitalization(value.source, value_capitalization))
    end
  end
end

def incorrect_separator?(text)

def incorrect_separator?(text)
  text[wrong_separator]
end

def leading_comment_lines

def leading_comment_lines
  first_non_comment_token = processed_source.tokens.find { |token| !token.comment? }
  if first_non_comment_token
    0...first_non_comment_token.line
  else
    (0..)
  end
end

def line_range(line)

def line_range(line)
  processed_source.buffer.line_range(line)
end

def magic_comments

def magic_comments
  processed_source.each_comment_in_lines(leading_comment_lines)
                  .select { |comment| MagicComment.parse(comment.text).valid? }
                  .map { |comment| CommentRange.new(comment) }
end

def on_new_investigation

def on_new_investigation
  return unless processed_source.ast
  magic_comments.each do |comment|
    issues = find_issues(comment)
    register_offenses(issues) if issues.any?
  end
end

def register_offenses(issues)

def register_offenses(issues)
  fix_directives(issues[:directives])
  fix_values(issues[:values])
end

def replace_capitalization(text, style)

def replace_capitalization(text, style)
  return text unless style
  case style
  when :lowercase
    text.downcase
  when :uppercase
    text.upcase
  end
end

def replace_separator(text)

def replace_separator(text)
  text.tr(wrong_separator, correct_separator)
end

def supported_capitalizations

def supported_capitalizations
  cop_config['SupportedCapitalizations'].map(&:to_sym)
end

def valid_capitalization?(style)

def valid_capitalization?(style)
  return true unless style
  supported_capitalizations.include?(style)
end

def value_capitalization

def value_capitalization
  cop_config['ValueCapitalization']&.to_sym.tap do |style|
    unless valid_capitalization?(style)
      raise "Unknown `ValueCapitalization` #{style} selected!"
    end
  end
end

def wrong_capitalization?(text, expected_case)

def wrong_capitalization?(text, expected_case)
  return false unless expected_case
  case expected_case
  when :lowercase
    text != text.downcase
  when :uppercase
    text != text.upcase
  end
end

def wrong_separator

def wrong_separator
  style == :snake_case ? KEBAB_SEPARATOR : SNAKE_SEPARATOR
end