# Author: jkk.lapp@gmail.com, 2015

from generator import Generator
from solver import Solver
from tester import Tester
from parser import Parser
from optimizer import Optimizer

import sys, os, argparse


def write_case(c, n, m, f=None):
	gen = Generator(n, m)
	gen.generate_test_cases(c)
	gen.print_test_cases(c)
	if f:
		gen.print_test_cases_to_file(c, f)

def read_and_solve_case(input, out=None, best=False, first=False):
	parser = Parser(input)
	solver = Solver(0, [], first)
	if out:
		output_file = open(out, 'w')
	for i in range(parser.c):
		solver.customers = parser.read_next_case()
		solver.length = parser.current_n
		solver.compute_solutions()
		if best:
			sol = solver.get_optimal_solution()
		else:
			sol = solver.get_random_solution()
		if sol != "IMPOSSIBLE":
			solution_string = "Case #" + str(i + 1) + ": " + " ".join(sol)
		else:
			solution_string = "Case #" + str(i + 1) + ": " + sol
		print solution_string
		if out:
			output_file.write(solution_string + '\n')
	if out:
		output_file.close()

def optimize_solution(input, solution, method):
	parser = Parser(input)
	sols = open(solution, 'r')
	tester = Tester()
	opt = Optimizer([], [])
	for i in range(parser.c):
		case = parser.read_next_case()
		s = sols.readline().split(':')[1]
		s = s[:-1]
		if "IMPOSSIBLE" in s:
			print "Skipping case #" + str(i + 1) + " " + s
			continue
		parsed_s = s.split()
		opt.solution = parsed_s
		opt.case = case
		opt.current_mattes = sum([int(x) for x in opt.solution])
		opt.optimize(method)
		print "For case:"
		print case
		print "Optimizing solution: " + s + " ---> " + opt.get_solution()
	sols.close()
	parser.finish()


if __name__ == '__main__':
	# Check if the solution is provided by cmd line.

	opt_parser = argparse.ArgumentParser()
	opt_parser.add_argument("-i", "--input", help="Read case from a file.")
	opt_parser.add_argument("-o", "--output", help="Write output to a file.")

	gen_group = opt_parser.add_argument_group('Generate')
	
	gen_group.add_argument('-c', '--cases', dest='n_cases', nargs='?', type=int, 
                    	   help='Number of test cases to generate.')

	gen_group.add_argument('-N', '--colors', dest='n_colors', nargs='?', type=int, 
                    	   help='Max number of colors in the case.')

	gen_group.add_argument('-M', '--customers', dest='n_customers', nargs='?', type=int, 
                    	   help='Max number of customers in the case')

	#gen_group.add_argument('-go', '--write_case', action='store', help="The output file to write the case.")

	sol_group = opt_parser.add_argument_group('Solve')
	sol_group.add_argument("-b", "--best", action="store_true", default=False, help="Get always the best solution, as opposed to a random one.")
	sol_group.add_argument("-f", "--get-first-found", action="store_true", default=False, help="Get always the best solution, as opposed to a random one.")
	
	opt_group = opt_parser.add_argument_group('Optimize solution')

	opt_group.add_argument("-s", "--solution-file", help="Solution file generated by solver.")
	opt_group.add_argument("-m", "--method", help="Method to use when optmizing", choices=('matte_minimizer', 'random_optimizer'))

	args = opt_parser.parse_args()
	
	if args.n_cases:
		write_case(args.n_cases, args.n_colors, args.n_customers, args.output)

	if args.input and not args.solution_file:
		read_and_solve_case(args.input, args.output, args.best, args.get_first_found)

	if args.solution_file:
		print "opt"
		optimize_solution(args.input, args.solution_file, args.method)
