#!/usr/bin/env ruby
#
# Notify Slack!

require 'optparse'
require 'yaml'
require 'json'
require 'hashie'
require 'slack-notifier'

options = Hashie::Mash.new({
  webhook: ENV['SLACK_WEBHOOK'],
  channel: ENV['SLACK_CHANNEL'],
  username: ENV['SLACK_USERNAME'] || 'Robot',
  message: ENV['SLACK_MESSAGE'],
  icon_emoji: ENV['SLACK_EMOJI'] || ':glitch:',
  icon_url: ENV['SLACK_EMOJI'] || false,
  build_status: ENV['BUILD_STATUS']
})

OptionParser.new do |opts|
  opts.banner = "Usage: notify-slack <message>"

  opts.on("-w", "--webhook URL", "Slack webhook URL") do |v|
    if ![URI::HTTP, URI::HTTPS].include?(URI.parse(v).class)
      puts "Hook URL (#{v}) is invalid"
      exit 1
    end
    options[:webhook] = v
  end

  opts.on("-c", "--channel CHANNEL", "Slack channel") do |v|
    options[:channel] = v
  end

  opts.on("-u", "--username USERNAME", "Slack username") do |v|
    options[:username] = v
  end

  opts.on("-b", "--build-status STATUS", "Jenkins build status, will generate message") do |v|
    options[:build_status] = v
  end
end.parse!

# Read configuration file if present
config = Hashie::Mash.new(YAML.load(File.read("slack.yml"))) if File.exists?("slack.yml")
options = options.merge(config) if config

# If build_status is set ('success' | 'failure'), ignore message and generate
# a jenkins build status message.
if options.build_status
  git_log = %x[git log --format="[%h] %cn: %s" origin/master..#{ENV['GIT_BRANCH']}]
  success = options.build_status == 'success'
  options.message = %Q(#{success ? ':lul:' : ':notlikethis:'} <#{ENV['BUILD_URL']}|#{ENV['JOB_NAME']} build #{ENV['BUILD_DISPLAY_NAME']}> on #{ENV['GIT_BRANCH']} has #{success ? 'succeeded' : 'failed'}.)
  options.message << %Q( ```#{git_log}```) if git_log != ''
  options.username = 'Jenkins'
  options.icon_emoji = ':jenkins:'
else
  options.message ||= ARGV.shift
end

if !options.webhook ||
  !options.channel ||
  !options.message
  puts "Webhook, Channel and Message are required."
  exit 1
end

@slack = Slack::Notifier.new options.webhook,
  channel: options.channel,
  username: options.username,
  icon_emoji: options.icon_emoji,
  icon_url: options.icon_url

@slack.ping(options.message)
