#!/usr/bin/ruby.ruby2.7 
# -*- ruby -*-

$:.push(File.expand_path(File.dirname(__FILE__) + "/../lib"))

require 'gem2rpm'
require 'optparse'
require 'fileutils'
require 'open-uri'
require 'uri'
require 'yaml'

opts = OptionParser.new("Usage: #{$0} [OPTIONS] GEM")
opts.separator("  Convert ruby Gems to source RPMs and specfiles")
opts.separator("  Uses a template to generate the RPM specfile")
opts.separator("  from the Gem spec")

print_template_file = nil
template_file = nil
output_file = nil
local = false
srpm = false
deps = false
nongem = false
doc_subpackage = true
fetch = false
config_file = nil
config = {}

opts.separator("")
opts.separator("  Options:")
opts.on("-T", "--current-template", "Print the current template") do |val|
    print_template_file = true
end
opts.on("-t", "--template TEMPLATE", "Use TEMPLATE for the specfile") do |val|
    template_file = val
end
opts.on("-v", "--version", "Print gem2rpm's version and exit") do
    puts Gem2Rpm::VERSION
    exit 0
end
opts.on("-o", "--output FILE", "Send the specfile to FILE") do |val|
    output_file = val
end
opts.on("-s", "--srpm", "Create a source RPM") do |val|
    srpm = true
end
opts.on("-l", "--local", "Do not retrieve Gem information over
#{' '*36} the network. Use on disconnected machines") do |val|
    local = true
end
opts.on("-d", "--dependencies", "Print the dependencies of the gem") do |val|
    deps = true
end
opts.on("-n", "--nongem", "Generate a subpackage for non-gem use") do |val|
    nongem = true
end
opts.on("--no-doc", "Disable document subpackage") do |val|
  doc_subpackage = false
end
opts.on("--fetch", "Fetch the gem from rubygems.org") do |val|
  fetch = true
end
opts.on("--config FILE", "Path to gem2rpm.yaml") do |val|
  config_file = val
end
opts.separator("")
opts.separator("  Arguments:")
opts.separator("    GEM            the path to locally stored gem package file or the name")
opts.separator("                   of the gem when using --fetch.")
opts.separator("")

rest = opts.permute(ARGV)

template = nil
template_file ||= 'opensuse'
if template_file.nil?
  f = open("/etc/os-release", "r") if File.exists?("/etc/os-release")
  if f
    f.read.split('\n').each do |line|
      line.match(%r{^ID=(.*)$}) { |m| template_file=m[1] }
    end
    f.close
    f = nil
  end
  if template_file.eql? '"opensuse-tumbleweed"'
    $stderr.puts 'Using template opensuse on Tumbleweed'
    template_file = 'opensuse'
  end
end
if template_file.nil?
  template = Gem2Rpm::TEMPLATE
else
  begin
      f = open(template_file, "r") if File.exists?(template_file)
      f = open(File.join(Gem2Rpm.template_dir, template_file + '.spec.erb'), "r") unless f
  rescue Errno::ENOENT
      $stderr.puts "Could not open template #{template_file}. Aborting"
      exit(1)
  end
  template = f.read
  f.close
end

if print_template_file
  puts template
  exit 0
end

if rest.size != 1
    $stderr.puts "Missing GEMFILE"
    $stderr.puts opts
    exit(1)
end
gemfile = rest[0]

if fetch
  gem_uri = ''
  open("https://rubygems.org/api/v1/gems/#{gemfile}.json") do |f|
    gem_uri = f.read.match(/"gem_uri":\s*"(.*?)",/m)[1]
    gemfile = URI.parse(gem_uri).path.split('/').last
    open(gemfile, 'w') do |gf|
      gf.write(open(gem_uri).read)
    end
  end
end

srpmdir = nil
gemname = nil
srpmdir = nil
specfile = nil
if srpm
    gemname = Gem2Rpm::Package.new(gemfile).spec.name
    srpmdir = `/bin/mktemp -t -d gem2rpm-#{gemname}.XXXXXX`.chomp
    specfile = File::join(srpmdir, "rubygem-#{gemname}.spec")
    if output_file.nil?
        output_file = specfile
    end
end

if config_file
  begin
    config = YAML.load_file(config_file)
    config[:sources] ||= []
    config[:sources] << File.basename(config_file)
  rescue Exception => ex
    $stderr.puts "Failed to load config file '#{config_file}': #{ex}"
    exit 1
  end
end

# Produce a specfile
oldlicense = nil
if output_file.nil?
    Gem2Rpm::convert(gemfile, template, $stdout, nongem, local, doc_subpackage, oldlicense, config) unless deps
else
    begin
        if File.exists?(output_file)
          File.open(output_file, 'r') do |oldfile|
            oldfile.each_line do |line|
              m = line.match(%r{^License:\s*(\w.*)$})
              oldlicense = m[1] if m
            end
          end
        end
        out = open(output_file, "w")
        Gem2Rpm::convert(gemfile, template, out, nongem, local, doc_subpackage, oldlicense, config)
    ensure
        out.close()
    end
end

# Create a  source RPM
if srpm
    unless File::exist?(specfile)
        FileUtils::copy(output_file, specfile)
    end
    FileUtils::copy(gemfile, srpmdir)

    system("rpmbuild -bs --nodeps --define '_sourcedir #{srpmdir}' --define '_srcrpmdir #{Dir::pwd}' #{specfile}")
end

if deps
  Gem2Rpm::Package.new(gemfile).spec.dependencies.each do |dep|
    Gem2Rpm::Dependency.new(dep).requirement.each do |r|
      puts "rubygem(#{dep.name}) #{r}"
    end
  end
end
