#!/usr/bin/env ruby

# Run it like this:
#
#   ruby scripts/tuple_adder_generator.rb > src/main/scala/com/twitter/scalding/GeneratedTupleAdders.scala

$indent = "  "

TYPES = ('A'..'Z').to_a

def make_tuple_adder(cnt)
  other_cnts = (1..(22-cnt)).to_a
  puts "#{$indent}class Tuple#{cnt}Adder[#{TYPES[0..(cnt - 1)].join(",")}](tup : #{get_tuple(0, cnt)}) {"

  # Add the :+ method
  puts "#{$indent}#{$indent}def :+[#{TYPES[cnt]}](other : #{TYPES[cnt]}) = {"
  puts "#{$indent}#{$indent}#{$indent}(#{tup_get("tup", cnt)},other)"
  puts "#{$indent}#{$indent}}"

  # Add the +: method
  puts "#{$indent}#{$indent}def +:[#{TYPES[cnt]}](other : #{TYPES[cnt]}) = {"
  puts "#{$indent}#{$indent}#{$indent}(other,#{tup_get("tup", cnt)})"
  puts "#{$indent}#{$indent}}"

  other_cnts.each do |ocnt|
    puts
    puts "#{$indent}#{$indent}def ++[#{TYPES[cnt..(cnt + ocnt - 1)].join(",")}](other : #{get_tuple(cnt, ocnt)}) = {"
    puts "#{$indent}#{$indent}#{$indent}(#{tup_get("tup", cnt)},#{tup_get("other", ocnt)})"
    puts "#{$indent}#{$indent}}"
  end
  puts "#{$indent}}"
  puts
  puts "#{$indent}implicit def tup#{cnt}ToAdder[#{TYPES[0..(cnt - 1)].join(",")}](tup : Tuple#{cnt}[#{TYPES[0..(cnt - 1)].join(",")}]) = new Tuple#{cnt}Adder(tup)"
end

def get_tuple(cnt1, cnt2)
  "Tuple#{cnt2}[#{TYPES[cnt1..(cnt1 + cnt2 - 1)].join(",")}]"
end

def tup_get(name, cnt)
  (1..cnt).map{ |i| "#{name}._#{i}" }.join(",")
end

puts "// following were autogenerated by #{__FILE__} at #{Time.now} do not edit"
puts %q|package com.twitter.scalding

trait GeneratedTupleAdders {
|

(1..21).each { |c|
  make_tuple_adder(c)
  puts
}

puts "}"
puts "// end of autogenerated"
