#!/usr/bin/env ruby

require_relative '../lib/samus'
require 'optparse'
require 'tmpdir'

command =
  case ARGV.shift
  when 'install'
    Dir.mkdir(Samus::CONFIG_PATH) unless File.directory?(Samus::CONFIG_PATH)
    Dir.chdir(Samus::CONFIG_PATH) { system "git clone #{ARGV.shift}" }
    exit
  when 'update'
    Samus.config_paths.each do |path|
      Dir.chdir(path) do
        if File.directory?('.git')
          puts "[I] Updating #{path}"
          system 'git pull'
        else
          puts "[S] Skipping non-Git directory #{path}"
        end
      end
    end
    exit
  when 'show-cmd'
    stage = ARGV.shift
    if stage
      name = ARGV.shift
      if name
        Samus::Command.new(stage, name).show_help
      else
        Samus::Command.list_commands(stage)
      end
    else
      Samus::Command.list_commands
    end
    exit
  when 'publish', 'push'
    Samus::Publisher
  when 'build'
    Samus::Builder
  end

dry_run = false
zip_release = true
skip_restore = false
outfile = nil
docker = false
docker_image = "lsegal/samus:latest"
options = OptionParser.new do |opts|
  opts.banner  = "Usage: samus publish [options] <release_file> [release_file ...]\n"
  opts.banner += "       samus build [options] <version> [build.json]\n"
  opts.banner += "       samus show-cmd [stage] [name]\n"

  opts.separator ''
  opts.separator 'Options:'
  opts.on('--dry-run', "Print commands, don't run them") do |_v|
    dry_run = true
  end
  if command == Samus::Builder
    opts.on('--[no-]zip', 'Zip release file') do |zip|
      zip_release = zip
    end
    opts.on('-o FILE', '--output', 'The file (no extension) to generate') do |file|
      outfile = file
    end
    opts.on('--skip-restore', 'Skips restore after build completes') do
      skip_restore = true
    end
  end
  opts.on('--docker', 'Use Docker to build or publish') do |_v|
    docker = true
  end
  opts.on('--docker-image IMAGE', 'Which Docker image to use (default: lsegal/samus:latest)') do |img|
    docker_image = img
  end
end
options.parse!

if docker
  cmd = <<-COMMAND
    docker run --rm -v "#{Dir.home}:/root"
    -v "#{Dir.pwd}:/build" -w /build -it #{docker_image}
    sh -c "chmod 400 /root/.ssh/*" &&
    samus #{command == Samus::Builder ? 'build' : 'publish'} #{ARGV.join(' ')}
  COMMAND
  cmd = cmd.gsub(/ +/, ' ').delete("\n").strip
  puts "[C] #{cmd}"
  system(cmd)
  exit($?.to_i)
end

if command == Samus::Publisher
  ARGV.each do |dir|
    raise "Aborting due to missing path #{dir}" unless File.exist?(dir)
  end

  ARGV.each do |dir|
    if File.directory?(dir)
      command.new(dir).publish(dry_run)
    elsif File.file?(dir) # it has to be an archive
      Dir.mktmpdir do |tmpdir|
        system "tar -xzf #{dir} -C #{tmpdir}"
        command.new(tmpdir).publish(dry_run)
      end
    end
  end
elsif command == Samus::Builder
  ver = ARGV.shift
  raise 'Missing version' if ver.nil?
  Samus::Builder.build_version = ver.sub(/^v/, '')

  (ARGV.empty? ? ['samus.json'] : ARGV).each do |file|
    command.new(file).build(dry_run, zip_release, outfile, skip_restore)
  end
else
  puts options
  exit 1
end
