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

import pl.edu.pw.mini.jk.sg.game.common.DefenderMove;
import pl.edu.pw.mini.jk.sg.gteval.result.TimedTrainingResult;
import pl.edu.pw.mini.jk.sg.gteval.result.TimedTrainingResultFactory;


class MixedUctTrainingResultFactory<DM extends DefenderMove ,AM>  implements TimedTrainingResultFactory<DM, AM> {
    private final int iterations;
    private final int restarts;
    private final IterationResult<DM, AM, ?, ?, ?> bestIterationResult;

    public MixedUctTrainingResultFactory(final int iterations,
					 final int restarts,
					 final IterationResult<DM, AM, ?, ?, ?> bestIterationResult) {
	this.iterations = iterations;
	this.restarts = restarts;
	this.bestIterationResult = bestIterationResult;
    }

    @Override
    public TimedTrainingResult<DM, AM> create(final long timeMs) {
	return new MixedUctTrainingResult<>(bestIterationResult, timeMs, iterations, restarts);
    }


    public int getIterations() {
	return iterations;
    }

    public int getRestarts() {
	return restarts;
    }
    
    public static <DM extends DefenderMove, AM>  MixedUctTrainingResultFactory<DM, AM> joinRestarts(final MixedUctTrainingResultFactory<DM, AM> run1, final MixedUctTrainingResultFactory<DM, AM> run2) {
	return new MixedUctTrainingResultFactory<DM, AM>(
						 Math.max(run1.iterations, run2.iterations),
						 run1.restarts+run2.restarts,
						 (run1.bestIterationResult.optimalAttackerPayoff().defenderPayoff() < run2.bestIterationResult.optimalAttackerPayoff().defenderPayoff()) ? run2.bestIterationResult : run1.bestIterationResult
						 );
    }
}
