# jira2trac.rb
# by Jan Szumiec <jan.szumiec@infiniteloop.eu>

require 'rexml/document'
require 'date'
require 'sqlite3'

if ARGV.size < 2
  puts "Usage: jira2trac.rb <input RSS feed (XML)> <trac sqlite database filename>"
  exit
end

class String
  def quote
    "'#{gsub(/'/, "''")}'"
  end
end

class Numeric
  alias quote inspect
end

class NilClass
  def quote
    "NULL"
  end
end

class JIRAFeedConverter
  Ticket = Struct.new(:id, :type, :time, :changetime, :component, :severity, :priority, :owner, :reporter, :cc, :version, :milestone, :status, :resolution, :summary, :description, :keywords)
  class Ticket
    def to_sql
      columns = []; values = []
      each_pair do |k,v|
        columns << k
        values << v.quote
      end
      "(#{columns.join(',')}) VALUES (#{values.join(',')})"
    end
  end
  
  def initialize(input, output)
    @document = REXML::Document.new(File.new(input))
    @database = SQLite3::Database.new(output)
  end
  
  def process
    @database.transaction do
      @document.elements.each("/rss/channel/item") do |item|
        t = Ticket.new
        t.id, t.summary = parse_jira_title(item.elements["title"].text)
        t.type = item.elements["type"].text
        t.time = DateTime.parse(item.elements["created"].text).strftime("%s").to_i
        t.changetime = DateTime.parse(item.elements["updated"].text).strftime("%s").to_i
        t.component = item.elements["component"].text if item.elements["component"]
        t.severity = t.priority = item.elements["priority"].text
        t.reporter = item.elements["reporter"].text
        t.owner = item.elements["assignee"].text
        t.status = item.elements["status"].text
        t.resolution = item.elements["resolution"].text
        t.description = item.elements["description"].text
        @database.execute("INSERT INTO ticket #{t.to_sql}")
      end
    end
  end
  
  def parse_jira_title(title)
    identifier, title = title.split(/ /, 2)
    _, identifier = identifier[1..-2].split(/-/, 2)
    return identifier.to_i, title
  end
end

JIRAFeedConverter.new(ARGV[0], ARGV[1]).process
