#!/usr/bin/ruby.ruby3.4 
# frozen_string_literal: true

require_relative "../lib/yaml_janitor"

def print_usage
  puts <<~USAGE
    Usage: yaml-janitor [options] <file_or_directory>

    yaml-janitor is a YAML linter and formatter that preserves comments.

    Options:
      --fix               Format files in-place (without this, just check)
      --diff              Show diff of formatting changes
      --config PATH       Path to config file (default: .yaml-janitor.yml)
      --indentation N     Number of spaces for indentation (default: 2)
      --line-width N      Maximum line width (default: 80)
      --help              Show this help message

    Examples:
      # Check files (report issues)
      yaml-janitor config.yml
      yaml-janitor containers/

      # Format files in-place
      yaml-janitor --fix config.yml
      yaml-janitor --fix --indentation 4 containers/

      # Show diff of formatting changes
      yaml-janitor --diff config.yml
  USAGE
  exit 0
end

# Parse args
fix = false
diff = false
config_path = nil
config_overrides = {}
paths = []

i = 0
while i < ARGV.length
  case ARGV[i]
  when "--fix"
    fix = true
  when "--diff"
    diff = true
  when "--config"
    i += 1
    config_path = ARGV[i]
  when "--indentation"
    i += 1
    config_overrides[:indentation] = ARGV[i].to_i
  when "--line-width"
    i += 1
    config_overrides[:line_width] = ARGV[i].to_i
  when "--help", "-h"
    print_usage
  else
    paths << ARGV[i]
  end
  i += 1
end

if paths.empty?
  puts "Error: No files or directories specified"
  print_usage
end

# Look for default config if not specified
if !config_path && File.exist?(".yaml-janitor.yml")
  config_path = ".yaml-janitor.yml"
end

# Process files
config = YamlJanitor::Config.new(config_path: config_path, overrides: config_overrides)
linter = YamlJanitor::Linter.new(config: config)
total_files = 0
files_with_violations = []
formatted_files = []
failed_files = []

paths.each do |path|
  if File.directory?(path)
    # Process all YAML files in directory
    yaml_files = Dir.glob(File.join(path, "**", "*.{yml,yaml}"))
    yaml_files.each do |file|
      total_files += 1
      result = linter.lint_file(file, fix: fix)

      if result[:error]
        failed_files << { file: file, error: result[:error] }
        puts "✗ #{file}: #{result[:error].message}"
      elsif result[:violations].any?
        files_with_violations << file
        if fix
          formatted_files << file
          puts "✓ #{file} (formatted)"
        elsif diff
          puts "✗ #{file}: needs formatting"
          puts linter.generate_diff(result[:original], result[:formatted], file)
          puts ""
        else
          puts "✗ #{file}: needs formatting"
        end
      elsif !fix && !diff
        puts "✓ #{file}"
      end
    end
  elsif File.file?(path)
    # Process single file
    total_files += 1
    result = linter.lint_file(path, fix: fix)

    if result[:error]
      failed_files << { file: path, error: result[:error] }
      puts "✗ #{path}: #{result[:error].message}"
    elsif result[:violations].any?
      files_with_violations << path
      if fix
        formatted_files << path
        puts "✓ #{path} (formatted)"
      elsif diff
        puts "✗ #{path}: needs formatting"
        puts linter.generate_diff(result[:original], result[:formatted], path)
        puts ""
      else
        puts "✗ #{path}: needs formatting"
      end
    elsif !fix && !diff
      puts "✓ #{path}"
    end
  else
    puts "Warning: #{path} not found"
  end
end

# Summary
puts "\n" + "="*60
if fix
  puts "Formatted #{formatted_files.length}/#{total_files} files"
else
  puts "Checked #{total_files} files"
  puts "#{files_with_violations.length} files need formatting"
end

if failed_files.any?
  puts "\nFailed files:"
  failed_files.each do |failure|
    puts "  #{failure[:file]}: #{failure[:error].message}"
  end
  exit 1
elsif files_with_violations.any? && !fix
  puts "\nRun with --fix to format these files"
  exit 1
else
  puts "✓ All files clean!"
  exit 0
end
