#!/usr/bin/ruby
# frozen_string_literal: true

# Copyright (C) 2017-2020 David Sugar <tychosoft@gmail.com>
#
# This file is free software; as a special exception the author gives
# unlimited permission to copy and/or distribute it, with or without
# modifications, as long as this notice is preserved.

['optparse', 'fileutils'].each {|mod| require mod}

EXTS = ['.dsc', '.deb', '.changes'].freeze

verbose = false
preserve = true
header = 'Copying'
banner = 'Usage: deb-archive [options] [debian-files...] target-directory'
force = false
move = false

# parse main arguments
OptionParser.new do |opts|
  opts.banner = banner

  opts.on('-f', '--[no-]force', 'force overwrite') do |f|
    force = f
  end

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

  opts.on('-m', '--move', 'move rather than copy') do
    header = 'Moving'
    move = true
  end

  opts.on('-np', '--no-preserve', 'Do not preserve file stats') do
    preserve = false
  end

  opts.on('-v', '--[no-]verbose', 'Offer verbose output') do |v|
    verbose = v
  end
end.parse!

# positional arguments and verification
*files, target = *ARGV
fileopts = {force: force}

abort(banner) if ARGV.size < 2
abort("*** deb-archive: #{target}: not a directory") unless File.directory?(target)

# process file list
files.each do |file; ext, basename, origin|
  ext = File.extname(file)
  basename = File.basename(file)
  dest = "#{target}/#{basename}"

  abort("*** deb-archive: #{basename}: not found") unless File.file?(file)
  abort("*** deb-archive: #{basename}: not debian source control") unless EXTS.include?(ext)
  abort("*** deb-archive: #{basename}: target exists") if File.file?(dest) && !force
  origin = File.dirname(file)
  print "#{header} #{basename}...\n" if verbose == true
  FileUtils.copy_file(file, dest, preserve) if move == false
  unless ext === '.deb'
    File.open(file, 'r') do |dsc; line, source, to|
      while (line = dsc.gets)
        next unless line=~/^Files/...line=~/^$/
        next if line =~/^$/ || line.strip! =~ /^Files/

        source = line.split[-1].prepend("#{origin}/")
        to = "#{target}/#{File.basename(source)}"
        next unless File.file?(source)

        print "#{header} #{File.basename(source)}...\n" if verbose == true
        FileUtils.copy_file(source, to, preserve) if move == false
        FileUtils.move(source, to, fileopts) if move == true
      end
    end
  end
  FileUtils.move(file, dest, fileopts) if move == true
end
