#!/usr/bin/ruby

DockerBinaryLocation = `which docker`.chomp

def cmd(*args)
  io = IO.popen(args, err: '/dev/null')
  io.read.split("\n")
end

def docker(*args)
  cmd(DockerBinaryLocation, *args)
end

output_type = (ARGV.delete('-n') or ARGV.delete('--by-name')) ? :name : :id
show_only_running = not(ARGV.delete('-a') or ARGV.delete('--all'))

unless pattern = ARGV.shift
  $stderr.puts "usage: #{$0} /search-pattern/"
  Kernel.exit 1
end

if pattern.index(':')
  pattern_name, pattern_tag = pattern.split(':')
  pattern = {name: pattern_name, tag: pattern_tag}
else
  pattern = {name: pattern, tag: 'latest'}
end

images = docker('images', '--no-trunc', pattern[:name])[1..-1].map do |ln|
  parts = ln.split(' ').map{ |part| part unless part == '<none>' }
  {tag: parts[1], ref: parts[2]}
end

pattern[:ref] = images.find{ |image| image[:tag] == pattern[:tag] }[:ref]
pattern[:tags] = images.find_all{ |image| image[:ref] == pattern[:ref] }.map{ |image| image[:tag] }

only_running_stanza = show_only_running ? [] : ['-a']
containers = docker('ps', *only_running_stanza, '--no-trunc')[1..-1].map do |ln|
  parts = ln.split(' ').map{ |part| part unless part == '<none>' }
  image_repo = parts[1]
  image_name, image_tag = image_repo.split(':')
  {id: parts[0], name: parts[-1], image: {repo: image_repo, name: image_name, tag: image_tag}}
end

containers = containers.find_all do |cont|
  (pattern[:name] == cont[:image][:name]) and pattern[:tags].include?(cont[:image][:tag])
end

containers.each do |cont|
  puts cont[output_type]
end
