#!/usr/bin/env ruby
# encoding: UTF-8

# Atlassian Stash and Pivotal Tracker Integration
# ===============================================
# - Post commit message details on Pivotal Tracker's user story

# Usage
# =====
# Create a branch with hash(#) + user story id. (#123467)
# Ex:
#   ch_#12345678_short_description_of_the_story - Chore
#   ft_#12345678_short_description_of_the_story - Features
#   bg_#12345678_short_description_of_the_story - Bug
#   rl_#12345678_short_description_of_the_story - Release
#
# If the branch name don't have a user story ID,
# then, add a branch ID in square bracket along with commit message.
# Ex:
#    [#12345678] Create a new file
#    Create a new file [#12345678]
#    Create a [#12345678] new file

require 'net/https'
require 'json'

class GitLogs
  attr_accessor :raw_log, :commit_data

  def initialize
    self.raw_log = `git log --no-color --format='Commit: %h%nAuthor: %aN <%aE>%nMessage: %s%nRefs: %d' -1`.force_encoding('utf-8')

    parse!
    self
  end

  def parse!
    regexp  = /Commit:\ (.*)\nAuthor:\ (.*)\nMessage:\ (.*)\nRefs:\ \ \((.*)\)/i
    match   = raw_log.scan(regexp).flatten
    self.commit_data = GitLog.new(match[0], match[1], match[2], match[3])
  end

  def pivotal_sync!
    Pivotal.new(commit_data).send! if commit_has_story_id?
  end

  def commit_has_story_id?
    !commit_data.message.scan(/\[+\#(\d+)\D?(.*)\]/).empty?
  end
end

class GitLog
  attr_accessor :hash, :author, :message, :refs

  SOURCE_CONTROL_URL = 'http://www.ida-gds.com/stash/projects/BGP/repos/bgp-react/commits/'

  def initialize hash, author, message, refs
    self.hash     = hash
    self.author   = author
    self.message  = message
    self.refs     = refs

    updated_message
  end

  def updated_message
    return message if ids_from_refs.empty?

    ids = ids_from_refs.join(' ')
    self.message = if message.scan(/\[(.+)\]/).empty?
      "[#{ids}] #{message}"
    else
      index = message.index('[') + 1
      message.insert index, "#{ids} "
    end
  end

  def ids_from_refs
    refs.split(',').inject([]) do |result, ref|
      id = ref.scan(/\#(\d+)\D/i).flatten
      result << "##{id.first}" unless id.empty?
      result
    end.flatten
  end

  def to_json
    { source_commit:
      { commit_id:  self.hash,
        author:     self.author,
        message:    self.message,
        url: "#{SOURCE_CONTROL_URL}#{self.hash}"
      }
    }.to_json
  end
end

class Pivotal
  attr_accessor :git_log, :tracker_token

  BASE_URI = URI('https://www.pivotaltracker.com/')

  def initialize git_log
    self.git_log        = git_log
    self.tracker_token  = get_token
  end

  def get_token
    `git config --get pivotal.token`.strip
  end

  def send!
    https = Net::HTTP.start(BASE_URI.host, 443, {
      use_ssl:      true,
      verify_mode:  OpenSSL::SSL::VERIFY_NONE
    })

    request = Net::HTTP::Post.new('/services/v5/source_commits')
    request['X-TrackerToken'] = tracker_token
    request['Content-type']   = 'application/json'
    request.body              = git_log.to_json

    response                  = https.request(request)
    puts "********* Commit posted successfully on Pivotal Tracker *********"
  end
end

GitLogs.new().pivotal_sync!
