#!/usr/bin/ruby

require 'json'
require 'optparse'

require 'debci'
require 'debci/package_status'

$all = false
$json = false
$status_file = false
$field = 'status'

optparse = 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|
    Debci.config!(arch: arch)
  end

  opts.on('-s SUITE', '--suite SUITE', 'Sets suite to act on') do |suite|
    Debci.config!(suite: suite)
  end

  opts.on('-l', '--all', 'show status for all packages') do
    $all = true
  end

  opts.on('j', '--json', 'outputs JSON') do
    $json = true
  end

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

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

if !$all && ARGV.size == 0
  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, $field => nil }
  end
end

if $all
  packages = `debci-list-packages`.split
else
  packages = ARGV
end

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

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

if !$all && packages.size == 1
  status = results[packages.first]&.first
  if $json
    if $status_file
      puts JSON.pretty_generate(status.job.as_json)
    else
      puts((status && status.job[$field]).to_json)
    end
  else
    puts(format_field(status && status.job[$field]))
  end
elsif $json
  puts JSON.pretty_generate(results.values.flatten.map(&:job).as_json)
else
  max_length = packages.map(&:length).max
  fmt = "%-#{max_length}s %s"
  packages.each do |pkg|
    status = results[pkg]&.first
    puts fmt % [pkg, format_field(status && status.job[$field])]
  end
end
