#!/usr/bin/env ruby

##
# This script was generated by Deja Vu.
# (You probably shouldn't modify it.)
##

def main
    #dv_frequency
    #dv_backupCommand
    #dv_sourceFolders
    #dv_destFolders
    #dv_logfile
    #dv_lastBackup
    
    # These two files are regenerated each time
    File.delete(logfile) if FileTest.exist?(logfile)
    File.delete(lastBackup) if FileTest.exist?(lastBackup)
    
    begin
        redirectTo(logfile) {
            puts ""
            puts Time.now.to_s + "  Deja Vu - #{frequency} backup beginning"
            for i in 0...sourceFolders.length
                # Make sure both devices are available first
                if FileTest.exist?(sourceFolders[i]) and FileTest.exist?(destFolders[i])
                    # Make sure there's enough space on the destination device
                    sourceSize = `du -ksx "#{sourceFolders[i]}"`.split[0].to_i
                    nameConflict = false
                    if not isEntireVolume(sourceFolders[i])
                        # Create parent folder at destination if needed
                        # and/or append it to the destination path
                        parentFolder = sourceFolders[i].split("/").last
                        destFolder = destFolders[i].split("/").last
                        if destFolder != parentFolder
                            if FileTest.exist?(destFolders[i] + "/" + parentFolder)
                                if FileTest.directory?(destFolders[i] + "/" + parentFolder)
                                    destFolders[i] += "/" + parentFolder
                                else
                                    nameConflict = true
                                end
                            else
                                destFolders[i] += "/" + parentFolder
                                Dir.mkdir(destFolders[i])
                                s = File.stat(sourceFolders[i])
                                File.chmod(s.mode, destFolders[i])
                                File.chown(s.uid, s.gid, destFolders[i])
                            end
                        end
                    end
                    destFolderSize = `du -ksx "#{destFolders[i]}"`.split[0].to_i
                    destAvail = `df -k "#{destFolders[i]}"`.split("\n")[1].split[3].to_i
                    destAvail += destFolderSize
                    if sourceSize < destAvail
                        if not nameConflict
                            puts ""
                            puts `#{backupCommand} "#{sourceFolders[i]}" "#{destFolders[i]}"`
                            if isEntireVolume(sourceFolders[i]) and isSystemDisk(sourceFolders[i])
                                # Bless System folder(s)
                                puts `bless -folder "#{destFolders[i]}/System/Library/CoreServices"`
                                if FileTest.exist?("#{destFolders[i]}/System Folder")
                                    puts `bless -folder9 "#{destFolders[i]}/System Folder" -bootBlocks`
                                end
                                File.delete("#{destFolders[i]}/Library/Caches/com.apple.LaunchServices.LocalCache.csstore")
                                File.delete("#{destFolders[i]}/var/db/networkinterfaces.xml")
                            end
                        else
                            puts ""
                            puts "PROBLEM: Deja Vu was unable to backup \"#{sourceFolders[i]}\"."
                            puts "REASON: There was a filename conflict in the destination directory."
                        end
                    else
                        puts ""
                        puts "PROBLEM: Deja Vu was unable to backup \"#{sourceFolders[i]}\"."
                        puts "REASON: There was not enough space on the destination disk."
                    end
                else
                    puts ""
                    puts "PROBLEM: Deja Vu was unable to backup \"#{sourceFolders[i]}\"."
                    puts "REASON: One of the required disks was unavailable."
                end
            end
            puts ""
            puts Time.now.to_s + "  Deja Vu - #{frequency} backup complete"
            puts ""
        }
    rescue Exception
        redirectTo(logfile) {
            puts ""
            puts "Backup Failed: " + $!
        }
    ensure
        redirectTo(lastBackup) {
            puts Time.now.strftime("%m/%d/%y")
        }
    end
end

def isEntireVolume(path)
    isRootOfMountedVolume = (path.split("/")[1] == "Volumes" and path.split("/").length == 3)
    return (path == "/" or isRootOfMountedVolume)
end

def isSystemDisk(path)
    systemItems = [ "Applications", "Library", "System", "Users", "Volumes", "private", "usr", "bin", "sbin", "mach_kernel", ".hidden" ]
    systemDisk = true
    systemItems.each { |x|
        systemDisk = false if not Dir.entries(path).include?(x)
    }
    return systemDisk
end

def redirectTo(fn)
    olddefout = $defout
    oldstderr = $stderr
    open(fn, "a") do |file|
        $defout = file
        $stderr = file
        begin
            yield
        ensure
            $defout = olddefout
            $stderr = oldstderr
        end
    end
end

main
