#!/usr/bin/env ruby

require 'fileutils'

class Rsync

  def self.do_copy(source_files, destination, remove_sent, output_progress = true)
      
    files = ""
    operation = (remove_sent ? "Moving" : "Copying")
    fc_path = "\"#{__dir__}/fc.app/Contents/MacOS/fc\""
    
    source_files.each do |file|
      # Do not add the file if the source and destination directories are the same
      if destination.chomp("/") != File.dirname(file).chomp("/")
        escaped_file = file.gsub(/["`$\\]/){ |s| '\\' + s }
        files += "\"#{escaped_file}\" "
      end
    end
  
    return false if files == ""
  
    escaped_destination = destination.gsub(/["`$\\]/){ |s| '\\' + s }

    $dz.determinate(false)

    num_files = `#{fc_path} --dry-run #{files} \"#{escaped_destination}\"`

    overall_percent = 0
    last_output = 0
    last_operation_output = ""
    has_set_determinate = false

    # Now run the actual transfer and output the progress perecent
    remove_sent_option = (remove_sent ? "--remove-sent" : "")
                                         
    rsync = IO.popen("#{fc_path} #{remove_sent_option} #{files} \"#{escaped_destination}\" 2>&1 | tr -u \"\r\" \"\n\"") do |f|
      while line = f.gets do
        if line =~ /^Filename:(.*)/
          currently_copying_path = $1.split(File::SEPARATOR)[-1].strip
          destination_basename = File.basename(destination)
          begin_output = "#{operation} “#{currently_copying_path}” to “#{destination_basename}”"
          $dz.begin(begin_output) if last_operation_output != begin_output
          last_operation_output = begin_output
        elsif line =~ /(.*)%/
          file_percent = $1
          output = ((file_percent.to_f + overall_percent) / num_files.to_f).to_i
          if !has_set_determinate
            $dz.determinate(true)
            has_set_determinate = true
          end
          $dz.percent(output) if last_output != output and output_progress
          last_output = output
        elsif line =~ /###-SUCCESS-###/
          overall_percent += 100
        elsif line =~ /fc:/
          puts line
        end
      end
    end

    return true
  end
end
