#!/usr/bin/env ruby
require 'fileutils'
require 'optparse'
require 'net/https'

options = {}
OptionParser.new do |opts|
  opts.on("--outdir THE_PATH", "the output directory") do |outdir|
    options[:outdir] = outdir
  end
  opts.on("-v", "--[no-]verbose", "Run verbosely") do |v|
    options[:verbose] = v
  end
end.parse!

def get_kiwi_archive(path)
  kiwi_archive = Dir[File.join(path, '/*.kiwi.txz')]
  if kiwi_archive.length > 1
    abort('More than one kiwi archives found')
  elsif kiwi_archive.length == 0
    abort('No kiwi archive found')
  end

  kiwi_archive[0]
end

def extract_archive(archive, outdir)
  system("tar", "Jxf", archive, "-C", outdir)
end

def create_root_archive(outdir)
  system("tar", "cf", File.join(outdir, 'root.tar'), "-C", File.join(outdir, 'root/'), "etc/", "studio/")
  FileUtils.rm_rf(File.join(outdir, 'root'))
end

def rename_kiwi_config(outdir)
  File.rename(File.join(outdir, 'config.xml'), File.join(outdir, 'config.kiwi'))
end

def order_kiwi_repos(outdir, options = {})
  api_url = ENV["OBS_SERVICE_APIURL"]
  kiwi_config = File.join(outdir, 'config.kiwi')

  if api_url.to_s.empty?
    abort("No API url defined. This might be caused by using an older osc version.")
  end

  # We use osc locally as workaround because '/source?cmd=orderkiwirepos'
  # is currently not accessible via build.o.o due to login proxy restrictions
  if ENV["OSC_VERSION"].to_s.empty?
    result = order_via_http(api_url, kiwi_config, options)
  else
    result = order_via_osc(kiwi_config)
  end

  File.write(kiwi_config, result)
end

def order_via_http(api_url, kiwi_config, options)
  limit = 5
  response = send_order_request(api_url, kiwi_config, options)

  while response.kind_of?(Net::HTTPRedirection) && limit > 0
    response = send_order_request(response['location'], kiwi_config, options)
    limit -= 1
  end

  unless response.kind_of?(Net::HTTPSuccess)
    abort("Ordering kiwi repositories failed. Backend responded with '#{response.code} - #{response.message}'")
  end

  response.body
end

def order_via_osc(kiwi_config)
  cmd = "osc api -X POST /source?cmd=orderkiwirepos -f #{kiwi_config}"
  result = `#{cmd}`
  if result.to_s.empty?
    abort("Ordering kiwi repositories failed. Command: '#{cmd}' failed.")
  end
  result
end

def send_order_request(url, kiwi_config, options)
  uri = URI.parse(url)

  https = Net::HTTP.new(uri.host, uri.port)
  https.use_ssl = (uri.scheme == "https")
  https.set_debug_output($stdout) if options[:verbose]

  request = Net::HTTP::Post.new("/source?cmd=orderkiwirepos")
  request.body = File.read(kiwi_config)
  request.content_type = "text/xml"

  https.request(request)
end

current_path = Dir.pwd
outdir = options[:outdir]
unless File.directory?(outdir) || File.exist?(outdir)
  abort("Output directory does not exist")
end

kiwi_archive = get_kiwi_archive(current_path)
extract_archive(kiwi_archive, outdir)
create_root_archive(outdir)
rename_kiwi_config(outdir)
order_kiwi_repos(outdir, options)

