package pl.edu.pw.mini.jk.sg.gteval;

import argonaut.Json;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Locale;

import org.apache.commons.math3.random.Well19937c;
import petrus.gteval.BuildInfo;

import pl.edu.pw.mini.jk.sg.gteval.config.GtevalOptions;
import pl.edu.pw.mini.jk.sg.gteval.result.TimedTrainingResult;
import pl.edu.pw.mini.jk.sg.gteval.result.TrainingResult;
import pl.edu.pw.mini.jk.sg.mixeduct.MixedUctConfig;
import pl.edu.pw.mini.jk.sg.game.GameVariantRunnerResult;

public class App {
	public static void main(String[] args)
	    throws IOException, InterruptedException {
	    Locale.setDefault(Locale.US);
	    final GtevalOptions options = GtevalOptions.parseCommandlineOptions(args);
	    final Well19937c rng = new Well19937c();
	    final GameVariantRunnerResult<? extends TrainingResult<?,?>> result;
	    System.out.format("Git hash: %s\n", BuildInfo.gitCommit());
	    if (options.getMethodConfig() == MethodConfigDecoder.milpConfigInstance()) {
		result = MilpStrategy.milpPlayer(options);
	    } else if (options.getMethodConfig() instanceof GameVariantMethodConfig) {
		final GameVariantMethodConfig muConfig = (GameVariantMethodConfig)options.getMethodConfig();
		result = muConfig.performTraining(options.getGameVariantRunner(), rng);
	    } else {
		throw new IllegalArgumentException("bad game method");
	    }
	    
	    options.getJsonStrategyOutput().ifPresent((f) -> {
		    try(FileWriter fw = new FileWriter(f);
			BufferedWriter bw = new BufferedWriter(fw)) {
			bw.write(result.methodResult().getTrainingResultAsJson(
								options.getMethodConfig().name(),
								AppHelper.addCommitHash(options.getUnparsedMethodConfig()),
								result.gameComputationTime()
							    ).toString());
		    } catch (IOException ex) {
			throw new RuntimeException(ex);
		    }
		});

	    System.out.print(result.methodResult().methodStatistics());
	}
}
