#!/usr/bin/env ruby

require "bundler/setup"
require "aws-sdk"
require "net/http"
require "uri"
require "pathname"

class UpdateStatusImage
  include FileUtils

  SVG_CONTENT_TYPE = "image/svg+xml"

  attr_reader :config

  def initialize
    @config = {
      name: "trix",
      status_image_url: "https://saucelabs.com/browser-matrix/basecamp_trix.svg",
      s3_bucket: "trix-depot",
      s3_region: "us-east-1"
    }
  end

  def perform
    image_filename = status_image_key("#{config[:name]}-#{tag}.svg")
    tmp_image_path = tmp_path.join(image_filename)

    download_file config[:status_image_url], to: tmp_image_path
    puts "Downloaded #{tmp_image_path} from #{config[:status_image_url]}"

    upload_to_s3 tmp_image_path, key: image_filename, content_type: SVG_CONTENT_TYPE
    puts "Uploaded #{image_filename} to S3"

    if update_current_image?
      current_image_filename = status_image_key("#{config[:name]}-current.svg")
      upload_to_s3 tmp_image_path, key: current_image_filename, content_type: SVG_CONTENT_TYPE
      puts "Uploaded #{current_image_filename} to S3"
    end
  end

  def tag
    ENV["TRAVIS_TAG"] || ENV["TAG"]
  end

  def update_current_image?
    ENV["TRAVIS_TAG"]  || ENV["CURRENT"]
  end

  def status_image_key(filename)
    Pathname.new("test-status-images").join(filename).to_s
  end

  def tmp_path
    Pathname.new("tmp").join(config[:s3_bucket])
  end

  def s3_credentials
    if access_key = ENV["AWS_ACCESS_KEY_ID"] && access_secret = ENV["AWS_SECRET_ACCESS_KEY"]
      Aws::Credentials.new(access_key, access_secret)
    else
      Aws::SharedCredentials.new(profile_name: config[:name])
    end
  end

  def s3
    Aws::S3::Resource.new(credentials: s3_credentials, region: config[:s3_region])
  end

  def s3_bucket
    @s3_bucket ||= s3.bucket(config[:s3_bucket])
  end

  def upload_to_s3(from, key:, **options)
    object = s3_bucket.object(key)
    object.upload_file(from.to_s, options)
  end

  def download_file(url, to:)
    uri = URI.parse(url)

    http_object = Net::HTTP.new(uri.host, uri.port)
    http_object.use_ssl = true if uri.scheme == "https"

    http_object.start do |http|
      request = Net::HTTP::Get.new uri.request_uri
      http.read_timeout = 3000
      http.request request do |response|
        mkdir_p to.dirname
        open to.to_s, "w" do |io|
          response.read_body do |chunk|
            io.write chunk
          end
        end
      end
    end
  end
end

UpdateStatusImage.new.perform
