#!/usr/bin/env ruby

require 'rubygems'
require 'fog/aws'

class SyncReports
  ACTIONS = %w[get put].freeze

  attr_reader :options

  def initialize(options)
    @options = options

    perform_sync!
  end

  private

  def perform_sync!
    case options[:action]
    when 'get'
      get_reports!
    when 'put'
      put_reports!
    end
  end

  def get_reports!
    options[:report_paths].each { |report_path| get_report!(report_path) }
  end

  def put_reports!
    options[:report_paths].each { |report_path| put_report!(report_path) }
  end

  def get_report!(report_path)
    file = bucket.files.get(report_path)

    if file.respond_to?(:body)
      File.write(report_path, file.body)
      puts "#{report_path} was retrieved from S3."
    else
      puts "#{report_path} does not seem to exist on S3."
    end
  end

  def put_report!(report_path)
    bucket.files.create(
      key: report_path,
      body: File.open(report_path),
      public: true
    )
    puts "#{report_path} was uploaded to S3."
  end

  def bucket
    @bucket ||= storage.directories.get(options[:bucket])
  end

  def storage
    @storage ||=
      Fog::Storage.new(
        provider: 'AWS',
        aws_access_key_id: ENV['AWS_ACCESS_KEY_ID'],
        aws_secret_access_key: ENV['AWS_SECRET_ACCESS_KEY']
      )
  end
end

def usage!(error: 'action')
  print "\n[ERROR]: "
  case error
  when 'action'
    puts "Please specify an action as first argument: #{SyncReports::ACTIONS.join(', ')}\n\n"
  when 'bucket'
    puts "Please specify a bucket as second argument!\n\n"
  when 'files'
    puts "Please specify one or more file paths as third argument!\n\n"
  end
  puts "Usage: #{__FILE__} [get|put] bucket report_path ...\n\n"
  puts "Note: the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY environment "\
       "variables need to be set\n\n"
  exit 1
end

if $0 == __FILE__
  action = ARGV.shift
  usage!(error: 'action') unless SyncReports::ACTIONS.include?(action)

  bucket = ARGV.shift
  usage!(error: 'bucket') unless bucket
  usage!(error: 'files') unless ARGV.any?

  SyncReports.new(action: action, bucket: bucket, report_paths: ARGV)
end