#!/usr/bin/env ruby

require 'json'
require 'shellwords'
require 'time'

DEBUG = false

def log_file
  @log_file ||= begin
    at_exit { log_file.close }
    File.open('/Users/sjs/linky-notify.log', 'a')
  end
end

def log(line)
  log_file.puts(line) if DEBUG
end

def munge_invalid_encoding(s)
  s.chars.map { |c| c >= "\0" && c <= "\176" ? c : '?' }.join
end

def e(s)
  if !s.valid_encoding?
    puts "forcing encoding of #{s.inspect}"
    s = s.force_encoding('UTF-8')
    if !s.valid_encoding?
      puts "munging #{s.inspect}"
      s = munge_invalid_encoding(s)
    end
    puts "s is now #{s.inspect}"
  end
  Shellwords.escape(s)
end

def notify_command(title, url)
  "/Users/sjs/.rbenv/shims/terminal-notifier -title #{e(title)} -message #{e(url)} -open #{e(url)} -sender com.apple.Terminal 2>&1"
end

def main
  dir = ENV['WATCH_DIR']
  created = JSON.parse(ENV['WATCH_CREATED'])
  log "dir = #{dir}"
  log "created = #{created.inspect}"
  created.each do |filename|
    path = File.join(dir, filename)
    lines = File.readlines(path).map(&:strip)
    title, url = nil, nil
    until (title && url) || lines.empty?
      line = lines.shift
      next if line == ''

      if line =~ /^http/
        url ||= line
      else
        title ||= line
      end
    end
    if url
      command = notify_command(title || url, url)
      log "[#{Time.now.iso8601}] #{command}"
      output = `#{command}`
      unless $?.success?
        exit 1
      end
      archive_dir = File.join(dir, 'Archive')
      Dir.mkdir(archive_dir) unless File.exists?(archive_dir)
      File.rename(path, File.join(archive_dir, filename))
    else
      log "[#{Time.now.iso8601}] Failed to find URL in #{filename}: #{File.read(path)}"
    end
  end
rescue Exception => e
  log "#{e.class}: #{e.message}"
  log e.backtrace.join("\n")
end

main if $0 == __FILE__
