#!/usr/bin/ruby

print "This script attempts to show how to run an add/remove/replace brick transform.\n"

testcase = {}

# add your logical orderings as a 'test'.

# replica = 2, simple setup
tmp_a = []
tmp_b = []
tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/brick1'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/brick1'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/brick2'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/brick2'} )

tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/brick3'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/brick3'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/brick4'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/brick4'} )


tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/brick1'} )
tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/brick1'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/brick2'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/brick2'} )

tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/brick3'} )
tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/brick3'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/brick4'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/brick4'} )

# nothing should change, no delta.
testcase['test1'] = {'a' => tmp_a, 'b' => tmp_b}



tmp_a = []
tmp_b = []

# should this fail or not? is it a true delta, or is it a sorted delta? (eg: does it need the "default" order logic built in...)
tmp_a = []
tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/brick1'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/brick1'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/brick2'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/brick2'} )

tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/brick3'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/brick3'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/brick4'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/brick4'} )

# and then...

tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/brick1'} )
tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/brick1'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/brick2'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/brick2'} )

tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/brick3'} )
tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/brick3'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/brick4'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/brick4'} )

# (adding):

tmp_b.push( {'host' => 'annex5.example.com', 'path' => '/data/brick5'} )
tmp_b.push( {'host' => 'annex6.example.com', 'path' => '/data/brick5'} )

tmp_b.push( {'host' => 'annex5.example.com', 'path' => '/data/brick6'} )
tmp_b.push( {'host' => 'annex6.example.com', 'path' => '/data/brick6'} )


testcase['test2'] = {'a' => tmp_a, 'b' => tmp_b}

# XXX: can we hack it with version numbers ?
# in any case, this version surely should pass

tmp_a = []
tmp_b = []
tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/b000001'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/b000001'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/b000002'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/b000002'} )

tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/b000003'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/b000003'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/b000004'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/b000004'} )

###

tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/b000001'} )
tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/b000001'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/b000002'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/b000002'} )

tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/b000003'} )
tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/b000003'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/b000004'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/b000004'} )

# and then add:

tmp_b.push( {'host' => 'annex5.example.com', 'path' => '/data/b000005#v0002'} )
tmp_b.push( {'host' => 'annex6.example.com', 'path' => '/data/b000005#v0002'} )

tmp_b.push( {'host' => 'annex5.example.com', 'path' => '/data/b000006#v0002'} )
tmp_b.push( {'host' => 'annex6.example.com', 'path' => '/data/b000006#v0002'} )

testcase['test3'] = {'a' => tmp_a, 'b' => tmp_b}


# removal...
tmp_a = []
tmp_b = []

tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/brick1'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/brick1'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/brick2'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/brick2'} )

tmp_a.push( {'host' => 'annex5.example.com', 'path' => '/data/brick3'} )
tmp_a.push( {'host' => 'annex6.example.com', 'path' => '/data/brick3'} )


tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/brick4'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/brick4'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/brick5'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/brick5'} )

tmp_a.push( {'host' => 'annex5.example.com', 'path' => '/data/brick6'} )
tmp_a.push( {'host' => 'annex6.example.com', 'path' => '/data/brick6'} )




tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/brick1'} )
tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/brick1'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/brick2'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/brick2'} )

#tmp_b.push( {'host' => 'annex5.example.com', 'path' => '/data/brick3'} )
#tmp_b.push( {'host' => 'annex6.example.com', 'path' => '/data/brick3'} )

#tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/brick4'} )
#tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/brick4'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/brick5'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/brick5'} )

tmp_b.push( {'host' => 'annex5.example.com', 'path' => '/data/brick6'} )
tmp_b.push( {'host' => 'annex6.example.com', 'path' => '/data/brick6'} )


testcase['test4'] = {'a' => tmp_a, 'b' => tmp_b}


# both

tmp_a = []
tmp_b = []

tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/brick1'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/brick1'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/brick2'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/brick2'} )

tmp_a.push( {'host' => 'annex5.example.com', 'path' => '/data/brick3'} )
tmp_a.push( {'host' => 'annex6.example.com', 'path' => '/data/brick3'} )


tmp_a.push( {'host' => 'annex1.example.com', 'path' => '/data/brick4'} )
tmp_a.push( {'host' => 'annex2.example.com', 'path' => '/data/brick4'} )

tmp_a.push( {'host' => 'annex3.example.com', 'path' => '/data/brick5'} )
tmp_a.push( {'host' => 'annex4.example.com', 'path' => '/data/brick5'} )

tmp_a.push( {'host' => 'annex5.example.com', 'path' => '/data/brick6'} )
tmp_a.push( {'host' => 'annex6.example.com', 'path' => '/data/brick6'} )




tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/brick1'} )
tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/brick1'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/brick2'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/brick2'} )

#tmp_b.push( {'host' => 'annex5.example.com', 'path' => '/data/brick3'} )
#tmp_b.push( {'host' => 'annex6.example.com', 'path' => '/data/brick3'} )

#tmp_b.push( {'host' => 'annex1.example.com', 'path' => '/data/brick4'} )
#tmp_b.push( {'host' => 'annex2.example.com', 'path' => '/data/brick4'} )

tmp_b.push( {'host' => 'annex3.example.com', 'path' => '/data/brick5'} )
tmp_b.push( {'host' => 'annex4.example.com', 'path' => '/data/brick5'} )

tmp_b.push( {'host' => 'annex5.example.com', 'path' => '/data/brick6'} )
tmp_b.push( {'host' => 'annex6.example.com', 'path' => '/data/brick6'} )

tmp_b.push( {'host' => 'annex7.example.com', 'path' => '/data/brick7'} )
tmp_b.push( {'host' => 'annex8.example.com', 'path' => '/data/brick7'} )

tmp_b.push( {'host' => 'annex7.example.com', 'path' => '/data/brick8'} )
tmp_b.push( {'host' => 'annex8.example.com', 'path' => '/data/brick8'} )



testcase['test5'] = {'a' => tmp_a, 'b' => tmp_b}



tests = testcase.clone	# copy

def get_version_from_path(path)

	rindex = path.rindex('/')
	if rindex.nil?
		# TODO: error, brick needs a / character...
	end
	base = path[rindex+1, path.size-rindex]
	findv = base.rindex('#v')
	if findv.nil?
		return 0	# version 0 (non-existant)
	else
		version = base[findv+2, base.size-findv]
		if version.size < 1
			# TODO: error, version string is missing...
			# TODO: assume version 0 ?
			return -1
		end

		return version.to_i
	end
end

def get_versions(group)
	versions = []
	group.each do |x|
		v = get_version_from_path(x['path'])
		if not versions.include?(v)
			versions.push(v)
		end
	end
	return versions.sort	# should be all int's
end

def filter_version(group, version)

	result = []
	group.each do |x|
		v = get_version_from_path(x['path'])
		if v == version
			result.push(x)
		end
	end
	return result
end

result = {}

# apologies if the ruby is not optimal, i'm a puppet expert, not a ruby one :P
tests.keys.each do |group|

	# XXX: testing...
#	if group != 'test2'
#		next
#	end

	# transform from a to b
	a = tests[group]['a']
	b = tests[group]['b']
	puts 'a:'
	puts a

	puts 'b:'
	puts b

	ai = 0
	bi = 0

	add = []
	del = []
	while ((a.size - ai) > 0) and ((b.size - bi) > 0)
		# same element, keep going
		if a[ai] == b[bi]
			ai = ai + 1
			bi = bi + 1
			next
		end

		# the elements must differ

		# if the element in a, exists in b (later on, but anywhere is okay)
		if not a[ai].include?(b)
			# then it must be a delete operation of a[ai]
			del.push(a[ai])	# push onto delete queue...
			ai = ai + 1
			next
		end

		if a[ai].include?(b)
			# then it must be an add operation of b[bi]
			add.push(b[bi])	# push onto add queue...
			bi = bi + 1
			next
		end

#		# XXX or:
#		if not b[bi].include(a)
#			# then it must be an add operation of b[bi]
#		end

#		if b[bi].include(a)
#			# then it must be an delete operation of a[ai]	# if we stay in sync!
#		end
	end
	while (a.size - ai) > 0	# if there is left over a at the end...
		del.push(a[ai])	# push onto delete queue...
		ai = ai + 1
	end

	while (b.size - bi) > 0	# if there is left over b at the end...
		add.push(b[bi])	# push onto add queue...
		bi = bi + 1
	end

	puts '# group: ' + group
	puts 'add:'
	add.each do |x|
		puts x['host'] + ':' + x['path']
	end
	puts 'del:'
	del.each do |x|
		puts x['host'] + ':' + x['path']
	end
	puts "----------------------------------------------------------------\n"

end

#puts result

