#!/usr/bin/ruby.ruby2.5 
require "ytrello"
require "English"

if ARGV.empty? || ARGV[0].include?("-h")
  puts "Usage: #{$PROGRAM_NAME} bug_number"
  puts "  Creates a trello card for a bug, links the bug to the card"
  exit 0
end

setup_trello
setup_bicho

# abbreviate a SUSE product name
def abbrev(s)
  s
    .sub("openSUSE", "oS")
    .sub("SUSE Linux Enterprise Desktop", "SLED")
    .sub("SUSE Linux Enterprise Server",  "SLES")
    .sub("SUSE Container as a Service Platform 1.0", "CaaSP1")
    .sub(/\(.*\)/, "")          # remove superfluous abbreviation
    .sub(" SP", "-SP")
    .sub(" Factory", "-TW")     # Tumbleweed
    .tr(" ", "")
end

# Trello list IDs, see also show_list_ids
PRODUCT_LISTS = {
  /SLE[SD]15/     => "5952060e0e9190605c75863e", # SLE 15
  # "59a3db0f0fac7c99d1808ae9" is "SLE 15 Storage" but we can't autodetect that
  /SLE[SD]12-SP3/ => "57cfdbcc9ae10f3d1fb996d3", # SLE-12-SP3 Maintenance
  /SLE[SD]12-SP2/ => "5538994821027776154180eb", # SLE12-SP2 Maintenance
  /SLE[SD]12-SP1/ => "5502d6719b0d5db70bcf6655", # SLE12-SP1 maintenance
  /SLE[SD]12/     => "5507f04f2c885ffbdd53208a", # SLE12-maintenance
  /SLE[SD]11/     => "5507f140ab44b6bcfcc6c561", # SLE11-maintenance
  /^oS/           => "550800984de3079fa9ded12a", # openSUSE
  /CaaSP1/        => "5877cf5650f2787cf6eb25a1", # CaaSP 1.0
  # fallback
  /./             => "5507f28d31c1cfac7a83eb72" # Generic Ideas
}.freeze

def product_to_list(product)
  PRODUCT_LISTS.to_a.each do |pattern, list_id|
    return list_id if product =~ pattern
  end
  raise "Internal error, PRODUCT_LISTS did not match"
end

def markdown_link(text, url)
  "[#{text}](#{url})"
end

def bz_markdown_link(id)
  markdown_link("bsc##{id}", "#{BUGZILLA_URL}/show_bug.cgi?id=#{id}")
end

def bicho_details(bug_id)
  bug = Bicho.client.get_bugs(bug_id).first
  raise "Bug ##{bug_id} not found" unless bug
  bug.priority =~ /^(\S+)\s/
  { summary: bug.summary, product: bug.product, priority: Regexp.last_match(1) }
end

# create a card description text
# @param bug_id bug number
# @return [String] description text in the Markdown format
def card_description(bug_id)
  descr = <<TXT
Bugzilla: #{bz_markdown_link(bug_id)}

---
## Review
- Pull Request: *URL here*
TXT

  # just to avoid the trailing blank errors in the heredoc
  descr + "- "
end

bug_id      = ARGV[0]
details     = bicho_details(bug_id)
product     = abbrev(details[:product])
card_name   = "#{product} (#{details[:priority]}) ##{bug_id} #{details[:summary]}"
description = card_description(bug_id)
list_id     = product_to_list(product)
# list_id     = "546336636415e12617f88e47" # My work / Done

debug "Trello query"
inc_board = Trello::Board.find(INC_BOARD_ID) || raise
t1_board = Trello::Board.find(TEAM_1_BOARD_ID) || raise
ta_board = Trello::Board.find(TEAM_A_BOARD_ID) || raise

labels = inc_board.labels(false) # false: objects; true: names
new_item_label = labels.find { |i| i.name =~ /new.item/i } || raise

list = Trello::List.find(list_id) ||
  raise("Cannot find list #{list_id} to represent #{details[:product]}")

inc_cards  = to_array inc_board.cards
t1_cards   = to_array t1_board.cards
ta_cards   = to_array ta_board.cards

existing = (inc_cards + t1_cards + ta_cards).find_all do |c|
  c.name =~ /\D#{bug_id}\D/
end

card = nil
if existing.empty?
  debug "Creating"

  raise "Trying to add to already archived list '#{list.name}'" if list.closed

  card = Trello::Card.create(list_id: list_id,
                             name:    card_name,
                             desc:    description,
                             pos:     "top")
  card.add_label(new_item_label)
  puts "Created #{bug_id} => #{card.short_url}"
else
  puts "Card for bug already exists:"
  existing.each { |c| puts c.url }
  card = existing.first if existing.size == 1
end

if card
  debug "Assigning card URL in Bugzilla"
  system "ytrello", "addurl", bug_id.to_s, card.short_url.to_s
end
