# frozen_string_literal: true

require ‘dotenv/load’ require ‘time’

def record_all_cassettes(cassette_dir)

FileUtils.rm_rf(cassette_dir)
FileUtils.mkdir_p(cassette_dir)

puts 'Recording cassettes for all providers...'
run_tests
puts 'Done recording. Please review the new cassettes.'

end

def record_for_providers(providers, cassette_dir)

all_providers = RubyLLM::Provider.providers.keys.map(&:to_s)

if providers.empty?
  puts "Please specify providers or 'all'. Example: rake vcr:record[openai,anthropic]"
  puts "Available providers: #{all_providers.join(', ')}"
  return
end

invalid_providers = providers - all_providers
if invalid_providers.any?
  puts "Invalid providers: #{invalid_providers.join(', ')}"
  puts "Available providers: #{all_providers.join(', ')}"
  return
end

cassettes_to_delete = find_matching_cassettes(cassette_dir, providers)

if cassettes_to_delete.empty?
  puts 'No cassettes found for the specified providers.'
  puts 'Running tests to record new cassettes...'
else
  delete_cassettes(cassettes_to_delete)
  puts "\nRunning tests to record new cassettes..."
end

run_tests

puts "\nDone recording cassettes for #{providers.join(', ')}."
puts 'Please review the updated cassettes for sensitive information.'

end

def find_matching_cassettes(dir, providers)

cassettes = []

Dir.glob("#{dir}/**/*.yml").each do |file|
  basename = File.basename(file)

  providers.each do |provider|
    next unless basename =~ /^[^_]*_#{provider}_/ || # For first section like "chat_openai_"
                basename =~ /_#{provider}_[^_]+_/    # For middle sections like "_openai_gpt4_"

    cassettes << file
    break
  end
end

cassettes

end

def delete_cassettes(cassettes)

puts "Deleting #{cassettes.size} cassettes for re-recording:"
cassettes.each do |file|
  puts "  - #{File.basename(file)}"
  File.delete(file)
end

end

def run_tests

run_test_queue_rspec || abort('Tests failed')

end

def retimestamp_cassettes(cassette_dir)

timestamp = Time.now.utc.httpdate
updated_files = 0
updated_entries = 0

Dir.glob("#{cassette_dir}/**/*.yml").each do |file|
  content = File.read(file)
  replacements = 0

  updated = content.gsub(/^(\s*recorded_at:\s*).+$/) do
    replacements += 1
    "#{Regexp.last_match(1)}#{timestamp}"
  end

  next if replacements.zero?

  File.write(file, updated)
  updated_files += 1
  updated_entries += replacements
end

puts "Updated #{updated_entries} recorded_at entries in #{updated_files} cassette files."
puts "New recorded_at value: #{timestamp}"

end

namespace :vcr do

desc 'Record VCR cassettes (rake vcr:record[all] or vcr:record[openai,anthropic])'
task :record, :providers do |_, args|
  require 'fileutils'
  require 'ruby_llm'

  providers = args.extras.unshift(args[:providers]).compact.map(&:downcase)
  cassette_dir = 'spec/fixtures/vcr_cassettes'
  FileUtils.mkdir_p(cassette_dir)

  if providers.include?('all')
    record_all_cassettes(cassette_dir)
  else
    record_for_providers(providers, cassette_dir)
  end
end

desc 'Update recorded_at timestamps for all cassette entries'
task :retimestamp do
  cassette_dir = 'spec/fixtures/vcr_cassettes'
  retimestamp_cassettes(cassette_dir)
end

end