#!/usr/bin/ruby.ruby3.4 

$LOAD_PATH.push(File.expand_path(File.dirname(__FILE__) + '/../lib'))

require 'node2rpm'
require 'rpmspec'
require 'json'
require 'optparse'
require 'erb'
require 'ostruct'

def distro
  distro = ''
  open('/etc/os-release') do |f|
    f.each_line do |l|
      distro = l.strip.split('=')[1] if l.start_with?('ID=')
    end
  end
  distro ||= 'opensuse'
  distro
end

def form_source(arr)
  str = ''
  i = 0
  arr.each do |s|
    str << "Source#{i}:\t#{s.url}\n"
    i += 1
  end
  str
end

options = {}
os = distro
template = open(File.join(File.dirname(__FILE__) + '/../template/', os + '.spec.erb')).read
erb = ERB.new(template, nil, '-')

parser = OptionParser.new do |opts|
  opts.banner = 'Usage: node2rpm -m <mod> -v <ver> -p <path> [options]'
  opts.separator 'Generate a RPM from a node module.'
  opts.separator 'Specific Options:'

  opts.on('-m <mod>', 'Specify the mod (Required)') do |mod|
    options[:name] = mod
  end

  opts.on('-v <ver>', 'Specify the mod version (Latest by default)') do |ver|
    options[:version] = ver
  end

  opts.on('-r <dependency,range>', Array,
          'Exclude a versioned dependency (for package split)') do |mod|
    if options[:exclusion].nil?
      options[:exclusion] = { mod[0] => mod[1] }
    else
      options[:exclusion][mod[0]] = mod[1]
    end
  end

  opts.on('-p <path>',
          'The output path (Current directory by default)') do |path|
    options[:path] = path
  end

  opts.separator ''
  opts.separator 'Common Options:'
  opts.on_tail('-h', '--help', 'Show this message') do
    puts opts
    exit
  end

  opts.on_tail('--version', 'Show version') do
    puts Node2RPM::VERSION
    exit
  end
end
parser.parse!(ARGV)

puts 'Generating json...'
json, bower_pkgs = Node2RPM.generate(options[:name], options[:version], options[:exclusion])
version = Node2RPM.version(json)

# write the json file
options[:path] ||= '.'
dest_json = File.join(options[:path], options[:name] + '-' + version + '.json')
open(dest_json, 'w:UTF-8') { |f| f.write JSON.pretty_generate(json) }

# download the sources
puts 'Downloading sources...it may take a while'
sources = Node2RPM.sources(json)
Node2RPM.sourcedownload(sources, options[:path])
pkgjson = OpenStruct.new
pkgjson.url = options[:name] + '-' + version + '.json'
sources << pkgjson

# bower
puts 'Preparing bower_components.tgz...'
Node2RPM::Bower.new.prepare_components(bower_pkgs)
bower = OpenStruct.new
bower.url = 'bower_components.tgz'
sources << bower unless bower_pkgs.empty?

# write the specfile
dest_specfile = File.join(options[:path], options[:name] + '.spec')

if File.exist?(dest_specfile)
  f = open(dest_specfile).read
  # replace source, licenses and version
  sourceobj = RPMSpec::Source.new(f)
  oldsource = sourceobj.sources
  new_specfile = f.sub(sourceobj.inspect(oldsource), form_source(sources))
                  .sub(/License:.*?\n/m, "License:\t#{Node2RPM.licenses(json)}\n")
                  .sub(/Version:.*?\n/m, "Version:\t#{version}\n")
  puts "Updating #{options[:name]}.spec..."
  open(dest_specfile, 'w:UTF-8') { |f1| f1.write new_specfile }
else
  description = Node2RPM::Attr.new(options[:name], version).description
  homepage = Node2RPM::Attr.new(options[:name], version).homepage
  spec = OpenStruct.new
  spec.name = options[:name]
  spec.version = version
  spec.licenses = Node2RPM.licenses(json)
  spec.summary = description
  spec.homepage = homepage
  spec.description = description
  spec.sources = sources
  spec.year = Time.now.year
  puts "Generating #{options[:name]}.spec..."
  open(dest_specfile, 'w:UTF-8') { |f1| f1.write erb.result(binding) }
end

puts 'Everything successful. Congratulations!'
