#!/usr/bin/env ruby
$VERBOSE = 1

require 'optparse'
require 'ostruct'
require 'etc'
require 'net/http'
require 'logger'
require 'rexml/document'
require 'time'

log_file = File.join(ENV['HOME'], 'Library', 'Logs', 'backup_delicious.log')
$log = Logger.new(log_file, 'weekly')
$log.level = Logger::DEBUG

$log.info("Backup started")

options = OpenStruct.new
options.file = nil
options.user = Etc.getlogin
options.password = nil
opts = OptionParser.new do |opts|
  opts.on("-o", "--output-file [FILE]", "Write output to file") do |file|
    options.file = file
  end
  opts.on("-u", "--user [USER]", "Username to log in with") do |user|
    options.user = user
  end
end
opts.parse!(ARGV)
$log.debug("Options: " + options.inspect)

begin
  username = options.user
  password =
    `security find-internet-password -g -a #{username} -s del.icio.us 2>&1`.
    match(/password: \"(.*)\"/)[1]

  Net::HTTP.start("del.icio.us") do |http|
    request = Net::HTTP::Get.new('/api/posts/update')
    request.basic_auth username, password
    response = http.request(request)
    response.value
    document = REXML::Document.new response.body
    update_timestamp = Time.parse(document.root.attributes['time'])
  
    if (!options.file.nil? && File.exist?(options.file))
      file_timestamp = File.mtime(options.file)
      if update_timestamp <= file_timestamp
        $log.info("Already up-to-date: skipping download")
        next
      end
    end

    request = Net::HTTP::Get.new('/api/posts/all')
    request.basic_auth username, password
    response = http.request(request)
    response.value
    if options.file.nil?
      $log.debug("Writing response to stdout")
      print response.body
    else
      $log.debug("Writing response to file: #{options.file}")
      File.open(options.file, "w") { |f| f << response.body }
    end
  end
rescue Exception => e
  $log.error(e)
end
$log.info("Backup complete")