#!/usr/bin/ruby

require 'json'
require 'optparse'

require 'debci'
require 'debci/package_status'

options = {
  all: false,
  json: false,
  status_file: false,
  field: 'status'
}

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
    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-list-packages`.split : ARGV

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 !options[:all] && packages.size == 1
  status = results[packages.first]&.first
  if options[:json]
    if options[:status_file]
      puts JSON.pretty_generate(status.job.as_json)
    else
      puts((status && status.job[options[:field]]).to_json)
    end
  else
    puts(format_field(status && status.job[options[:field]]))
  end
elsif options[: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[options[:field]])]
  end
end
