import java.io.*;
import java.util.*;

public class TestsGen {

	static TestWriter testWriter = new TestWriter(false, "../tests/");
	static final Randomizer rnd = new Randomizer(556668949239L);

	static void genSample() throws IOException {
		testWriter.printSimpleTest(new DivisionTest(new int[] { 0, 0, 1, 1 },
				new int[] { 2, 3, 2, 3 }, 100, 100, true));
	}

	static void genVertical(int n, int fine) throws IOException {
		int[] x = new int[n];
		int[] y = new int[n];
		int t = 0;
		for (int i = 0; i < n - fine * fine + fine; i++) {
			x[t] = 0;
			y[t++] = i;
		}
		for (int i = 1; i < fine; i++) {
			for (int j = n / 2; j < n / 2 + fine; j++) {
				x[t] = i;
				y[t++] = j;
			}
		}
		testWriter.printSimpleTest(new DivisionTest(x, y, fine, n));
	}

	static void genHorizontal(int n, int fine) throws IOException {
		int[] x = new int[n];
		int[] y = new int[n];
		int t = 0;
		for (int i = 0; i < n - fine * fine + fine; i++) {
			x[t] = i;
			y[t++] = 0;
		}
		for (int i = 1; i < fine; i++) {
			for (int j = n / 2; j < n / 2 + fine; j++) {
				x[t] = j;
				y[t++] = i;
			}
		}
		testWriter.printSimpleTest(new DivisionTest(x, y, n, fine));
	}

	static void genDiagonal(int n, int fine, boolean... reverseX)
			throws IOException {
		int[] x = new int[n];
		int[] y = new int[n];
		int t = 0;
		for (int i = 0; i < n - fine * fine + fine; i++) {
			x[t] = i;
			y[t++] = i;
		}
		for (int diff = 1; diff < fine; diff++) {
			for (int j = n / 2; j < n / 2 + fine; j++) {
				x[t] = j + diff;
				y[t++] = j;
			}
		}
		if (reverseX.length > 0) {
			for (int i = 0; i < n; i++) {
				x[i] = n - i - 1;
			}
		}
		testWriter.printSimpleTest(new DivisionTest(x, y, n, n));
	}

	static void genMatr(int n, int m) throws IOException {
		int[] x = new int[n * m];
		int[] y = new int[n * m];
		int t = 0;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				x[t] = i;
				y[t++] = j;
			}
		}
		testWriter.printSimpleTest(new DivisionTest(x, y, n, m));
	}

	public static void genRandom(int cnt, int n, int m) throws IOException {
		HashSet<String> was = new HashSet<>();
		int[] x = new int[cnt];
		int[] y = new int[cnt];
		for (int i = 0; i < cnt; i++) {
			x[i] = rnd.nextInt(n);
			y[i] = rnd.nextInt(m);
			while (was.contains(x[i] + " " + y[i])) {
				x[i] = rnd.nextInt(n);
				y[i] = rnd.nextInt(m);
			}
			was.add(x[i] +" "+y[i]);
		}
		testWriter.printSimpleTest(new DivisionTest(x, y, n, m));
	}

	public static void genCorrectness() throws IOException {
		genVertical(100, 1);
		genHorizontal(100, 1);
		genDiagonal(100, 1);
		genVertical(100, 3);
		genHorizontal(100, 3);
		genDiagonal(100, 3, true);
		genMatr(10, 10);
		for (int i = 0; i < 3; i++) {
			genRandom(100, 15, 15);
			genRandom(100, 5, 50);
			genRandom(100, 50, 5);
			genRandom(100, 100, 100);
			genRandom(100, 30, 30);
		}
	}

	public static void genPerfomance() throws IOException {
		genVertical(100000, 1);
		genHorizontal(100000, 1);
		genDiagonal(100000, 1);
		genVertical(100000, 15);
		genHorizontal(100000, 15);
		genDiagonal(100000, 15, true);
		genMatr(500, 200);
		for (int i = 0; i < 3; i++) {
			genRandom(100000, 400, 400);
			genRandom(100000, 20, 50000);
			genRandom(100000, 50000, 20);
			genRandom(100000, 100000, 100000);
			genRandom(100000, 30000, 30000);
		}
	}

	public static void main(String[] args) throws IOException {
		new File("../tests").mkdir();
		genSample();
		genCorrectness();
		genPerfomance();
	}

}
