require 'csv'
require 'json'
require 'digest'
require 'open3'
root = __dir__
clean = ->(v) { v && !['', '\\N', '-'].include?(v.strip) ? v.strip : nil }
airlines = CSV.read(File.join(root, 'airlines.dat'), encoding: 'UTF-8').map do |r|
  raise 'Unexpected airline shape' unless r.length == 8
  iata = clean.call(r[3])&.upcase
  icao = clean.call(r[4])&.upcase
  {id: r[0].to_i, name: r[1], alias: clean.call(r[2]), iata: iata&.match?(/\A[A-Z0-9]{2}\z/) ? iata : nil, icao: icao&.match?(/\A[A-Z]{3}\z/) ? icao : nil, callsign: clean.call(r[5]), country: clean.call(r[6]), sourceActive: r[7], statusVerified: false}
end
patches = JSON.parse(File.read(File.join(root, 'airline-overrides.json')), symbolize_names: true)
patches.each do |patch|
  airline = airlines.find { |r| r[:id] == patch[:id] && r[:icao] == patch[:icao] }
  raise 'Airline correction no longer matches its source record' unless airline
  airline.merge!(patch)
end
enriched, status = Open3.capture2('node', File.join(root, 'enrich-airlines.mjs'), stdin_data: JSON.generate(airlines))
raise 'Airline enrichment failed' unless status.success?
enrichment = JSON.parse(enriched, symbolize_names: true)
airlines = enrichment[:entries]
patches.each do |patch|
  airline = airlines.find { |r| r[:id] == patch[:id] && r[:icao] == patch[:icao] }
  raise 'Airline correction no longer matches its source record' unless airline
  airline.merge!(patch)
end
aircraft = CSV.read(File.join(root, 'planes.dat'), encoding: 'UTF-8').map do |r|
  raise 'Unexpected aircraft shape' unless r.length == 3
  {name: r[0], iata: clean.call(r[1]), icao: clean.call(r[2])}
end
supplement = JSON.parse(File.read(File.join(root, 'aircraft-supplement.json')), symbolize_names: true)
# 767-400 is exclusively the ER model; retain the former label as a search alias.
aircraft.reject! { |r| r[:name] == 'Boeing 767-400' }
supplement.each do |r|
  aircraft.reject! { |old| old[:name] == r[:name] }
  aircraft << r
end
aircraft.each { |r| r[:catalogId] = 'model:' + r[:name].downcase.gsub(/[^a-z0-9]+/, '-') }
File.write(File.join(root, 'airlines.json'), JSON.generate(airlines))
File.write(File.join(root, 'aircraft.json'), JSON.generate(aircraft))
File.write(File.expand_path('../../lib/aircraft-reference.json', root), JSON.generate(aircraft)) if Dir.exist?(File.expand_path('../../lib', root))
stats = {airlines: airlines.length, airlineSourceActive: airlines.group_by{|a|a[:sourceActive]}.transform_values(&:length), aircraft: aircraft.length, aircraftWithIcao: aircraft.count{|a|a[:icao]}, aircraftWithIata: aircraft.count{|a|a[:iata]}, sha256: %w[airlines.dat planes.dat].to_h{|f|[f,Digest::SHA256.file(File.join(root,f)).hexdigest]}}
stats.merge!(enrichment[:stats])
stats[:airlinesWithIata] = airlines.count { |a| a[:iata] }
stats[:airlinesWithIcao] = airlines.count { |a| a[:icao] }
stats[:airlinesWithAliases] = airlines.count { |a| a[:alias] }
File.write(File.join(root, 'manifest.json'), JSON.pretty_generate(stats))
puts JSON.pretty_generate(stats)
