#!/usr/bin/env ruby

ENV["RAILS_ENV"] ||= "production"

APP_PATH = File.expand_path("../../config/application", __FILE__)
require File.expand_path("../../config/boot", __FILE__)
require APP_PATH
Rails.application.require_environment!

Story.to_tweet.each_with_index do |s, x|
  if x > 0
    sleep 2
  end

  tags = s.tags.pluck(:tag).map { |t| " #" + t }.join("")

  via = ""
  if s.user.twitter_username.present?
    via = "\n" +
      (s.user_is_author? ? "by" : "via") +
      " @#{s.user.twitter_username}"
  end

  tco_status = via +
    "\n" +
    ("X" * Twitter::TCO_LEN) + tags +
    (s.url.present? ? "\n" + ("X" * Twitter::TCO_LEN) : "")

  status = via +
    "\n" +
    s.short_id_url +
    tags +
    (s.url.present? ? "\n" + s.url : "")

  left_len = Twitter::MAX_TWEET_LEN - tco_status.length

  title = s.title
  if /^([dm] |@)/i.match?(title)
    # prevent these tweets from activating twitter shortcuts
    # https://dev.twitter.com/docs/faq#tweeting
    title = "- #{title}"
  end

  # if there are any urls in the title, they should be sized (at least) to a
  # twitter t.co url
  left_len -= title.scan(/[^ ]\.[a-z]{2,10}/i)
    .map { |_u| [0, Twitter::TCO_LEN].max }
    .inject(:+)
    .to_i

  if left_len < -3
    left_len = -3
  end

  status = if title.bytesize > left_len
    title[0, left_len - 3] + "..." + status
  else
    title + status
  end

  res = Twitter.oauth_request("/1.1/statuses/update.json", :post, "status" => status)

  begin
    if /\d+/.match?(res["id_str"].to_s)
      s.update_column("twitter_id", res["id_str"])
    elsif res["errors"].select { |e| e["code"] == 226 || e["code"] == 186 }.any?
      # twitter is rejecting the content of this message, skip it
      s.update_column("twitter_id", 0)
      puts "skipping: failed posting story #{s.id} (#{status.inspect}): #{res.inspect}\n"
    else
      raise
    end
  rescue => e
    puts "failed posting story #{s.id} (#{status.inspect}): #{e.inspect}\n#{res.inspect}"
    exit
  end
end
