#!/usr/bin/env ruby
# frozen_string_literal: true

# Deterministic sample-log generator for the Relaystation eval fixture.
# Produces relay-*.log and worker-*.log files under logs/ (default: the
# project root next to this script, or ARGV[0] if given). No Random, no
# Time.now — every byte of output is a pure function of loop indices, so
# running this script twice produces byte-identical files.

TARGET_DIR = ARGV[0] || File.expand_path('..', __dir__)
LOGS_DIR = File.join(TARGET_DIR, 'logs')

Dir.mkdir(LOGS_DIR) unless Dir.exist?(LOGS_DIR)

DAYS = %w[2026-07-01 2026-07-02 2026-07-03 2026-07-04].freeze
TENANTS = %w[acme globex initech umbrella soylent].freeze
SERVICES = %w[billing crm analytics email sms audit search webhooks reports].freeze
WORKERS = %w[worker-1 worker-2 worker-3 worker-4 worker-5].freeze

STEP_MS = 180
TOTAL_LINES = 760

def timestamp(date, index)
  total_ms = index * STEP_MS
  total_seconds = total_ms / 1000
  ms = total_ms % 1000
  hh = (total_seconds / 3600) % 24
  mm = (total_seconds / 60) % 60
  ss = total_seconds % 60
  format('%s %02d:%02d:%02d.%03d', date, hh, mm, ss, ms)
end

def event_id(index)
  format('evt_%04d', index % 10_000)
end

def fmt_line(date, index, level, component, message)
  "#{timestamp(date, index)} #{level} [#{component}] #{message}\n"
end

def routine_relay_line(date, index)
  tenant = TENANTS[index % TENANTS.length]
  service = SERVICES[index % SERVICES.length]
  case index % 4
  when 0
    fmt_line(date, index, 'INFO', 'ingest', "event #{event_id(index)} accepted from tenant #{tenant}")
  when 1
    fmt_line(date, index, 'INFO', 'dispatch', "event #{event_id(index)} delivered to service #{service}")
  when 2
    fmt_line(date, index, 'INFO', 'auth', "signature verified for tenant #{tenant}")
  else
    fmt_line(date, index, 'DEBUG', 'metrics', "events.ingested=#{index}")
  end
end

def routine_worker_line(date, index)
  worker = WORKERS[index % WORKERS.length]
  case index % 3
  when 0
    fmt_line(date, index, 'INFO', 'worker', "#{worker} processed #{event_id(index)} in #{(index % 40) + 5}ms")
  when 1
    fmt_line(date, index, 'DEBUG', 'heartbeat', "#{worker} heartbeat ok")
  else
    fmt_line(date, index, 'INFO', 'scaler', "pool size stable at #{WORKERS.length} workers")
  end
end

def write_relay_log(date, incident)
  path = File.join(LOGS_DIR, "relay-#{date}.log")
  File.open(path, 'w') do |f|
    (0...TOTAL_LINES).each do |index|
      f.write(incident.call(date, index) || routine_relay_line(date, index))
    end
  end
end

def write_worker_log(date, incident)
  path = File.join(LOGS_DIR, "worker-#{date}.log")
  File.open(path, 'w') do |f|
    (0...TOTAL_LINES).each do |index|
      f.write(incident.call(date, index) || routine_worker_line(date, index))
    end
  end
end

no_incident = ->(_date, _index) { nil }

# 2026-07-01 — routine traffic, no incidents.
write_relay_log('2026-07-01', no_incident)
write_worker_log('2026-07-01', no_incident)

# 2026-07-02 — relay: auth token expiry causes a 401 retry storm.
# worker: normal.
auth_storm = lambda do |date, index|
  next nil unless index >= 400 && index < 640

  offset = index - 400
  case offset % 3
  when 0
    fmt_line(date, index, 'WARN', 'auth', 'signature token expired for tenant acme')
  when 1
    fmt_line(date, index, 'ERROR', 'dispatch', 'upstream responded 401')
  else
    attempt = ((offset / 3) % 8) + 1
    fmt_line(date, index, 'INFO', 'retry', "scheduling retry (attempt #{attempt}) after 401")
  end
end
write_relay_log('2026-07-02', auth_storm)
write_worker_log('2026-07-02', no_incident)

# 2026-07-03 — routine traffic, no incidents.
write_relay_log('2026-07-03', no_incident)
write_worker_log('2026-07-03', no_incident)

# 2026-07-04 — worker-3 dies, capacity drops, queue fills, events are
# dropped. Worker heartbeat misses begin shortly before the relay's queue
# depth escalation starts.
worker_death = lambda do |date, index|
  if index >= 550 && index < 660 && (index - 550) % 20 == 0
    fmt_line(date, index, 'WARN', 'heartbeat', 'worker-3 heartbeat missed')
  elsif index == 660
    fmt_line(date, index, 'ERROR', 'worker', 'worker-3 marked dead')
  end
end
write_worker_log('2026-07-04', worker_death)

queue_backup = lambda do |date, index|
  if index >= 600 && index < 700
    step = index - 600
    depth = 100 + (step * 4900 / 99)
    depth = 5000 if depth > 5000
    fmt_line(date, index, 'WARN', 'queue', "queue depth #{depth}")
  elsif index >= 700
    fmt_line(date, index, 'ERROR', 'dispatch', "DROPPED event #{event_id(index)} (queue full)")
  end
end
write_relay_log('2026-07-04', queue_backup)

puts "wrote #{DAYS.length * 2} log files to #{LOGS_DIR}"
