#!/usr/bin/ruby

require 'json'
require 'optparse'

require 'debci'
require 'debci/package_status'

options = {
  all: false,
  json: false,
  status_file: false,
  field: 'status',
  arch: Debci.config.arch,
  suite: Debci.config.suite,
}

OptionParser.new do |opts|
  opts.banner = 'Usage: debci status [OPTIONS] [PACKAGE]'
  opts.separator 'Options:'

  opts.on('-a ARCH', '--arch ARCH', 'Sets architecture to act on') do |arch|
    options[:arch] = arch
  end

  opts.on('-s SUITE', '--suite SUITE', 'Sets suite to act on') do |suite|
    options[:suite] = suite
  end

  opts.on('-l', '--all', 'show status for all packages') do
    options[:all] = true
  end

  opts.on('-j', '--json', 'outputs JSON') do
    options[:json] = true
  end

  opts.on('--status-file', 'outputs the full status file (implies --json)') do
    options[:status_file] = true
    options[:json] = true
  end

  opts.on('-f FIELD', '--field FIELD', 'displays FIELD from the status file (default: status)') do |f|
    options[:field] = f
  end
end.parse!

if !options[:all] && ARGV.empty?
  puts "debci-status: when not using -l/--all, one or more PACKAGEs have to be specified."
  exit 1
end

def get_status_file(pkg)
  # FIXME duplicates logic found elsewhere :-/
  prefix = pkg.sub(/^((lib)?.).*/, '\1')
  File.join(Debci.config.packages_dir, prefix, pkg, 'latest.json')
end

def read_status_file(pkg)
  status_file = get_status_file(pkg)
  if File.exist?(status_file)
    JSON.parse(File.read(status_file))
  else
    { 'package' => pkg, options[:field] => nil }
  end
end

packages = options[:all] ? Debci::Package.all.map(&:name) : ARGV

def format_field(v)
  v || 'unknown'
end

results = Debci::PackageStatus.includes(:package, :job).where(
  'packages.name': packages,
  suite: options[:suite],
  arch: options[:arch],
).group_by { |status| status.package.name }

if options[:json]
  output = []
else
  max_length = packages.map(&:length).max
  fmt = "%-#{max_length}s %s"
end

packages.each do |pkg|
  status = results[pkg]&.first
  if status && options[:status_file]
    output << results[pkg].flatten.map(&:job)
  elsif options[:json]
    output << { "package" => pkg,
                "status" => format_field(status && status.job[options[:field]]), }
  else
    puts fmt % [pkg, format_field(status && status.job[options[:field]])]
  end
end

puts JSON.pretty_generate(output.flatten.as_json) if options[:json]
