package no.valg.valgnatt.backend.mandatberegning.beregning;

import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import no.valg.valgnatt.database.Konstanter;
import no.valg.valgnatt.database.domene.ValgType;
import no.valg.valgnatt.database.geografi.Fylke;
import no.valg.valgnatt.database.geografi.Land;
import no.valg.valgnatt.database.geografi.Mandater;
import no.valg.valgnatt.database.geografi.PartiMandater;
import no.valg.valgnatt.database.hibernate.Valgdistrikt;
import no.valg.valgnatt.database.hibernate.ValgdistriktId;

import org.junit.Assert;
import org.junit.Test;

/**
 * Test med 3 fylker og 4 partier
 */
public class UtjevningsmandatTest {

	@Test
	public void beregn_Enkel() throws Exception {


		Land land = lagLand(ValgType.ST, 3, "A", "H", "FRP", "KRF");

		Map<String, Integer> distriktsmandaterPrFylke = new TreeMap<>();
		distriktsmandaterPrFylke.put("01", 10);
		distriktsmandaterPrFylke.put("02", 10);
		distriktsmandaterPrFylke.put("03", 10);

		leggTilStemmerSlikAtFRPOgKRFFårUtjevningsmandatene(land, false);


		UtjevningsmandatResultat resultat = Utjevningsmandat.beregnOgOppdater(land, distriktsmandaterPrFylke, false);

		Assert.assertEquals("FRP", resultat.getPartiPrFylke().get("01"));
		Assert.assertEquals("FRP", resultat.getPartiPrFylke().get("02"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("03"));
	}

	private void leggTilStemmerSlikAtFRPOgKRFFårUtjevningsmandatene(Land land, boolean leggTilStemmerForFI) {
		// Stemmer beregnet på landsnivå - alle er over sperregrensen
		land.getValgdistrikt().getPartiMandater("A").getResultatData().setStemmer(1000);
		land.getValgdistrikt().getPartiMandater("H").getResultatData().setStemmer(1000);
		land.getValgdistrikt().getPartiMandater("FRP").getResultatData().setStemmer(100);
		land.getValgdistrikt().getPartiMandater("KRF").getResultatData().setStemmer(99);
		if (leggTilStemmerForFI) {
			land.getValgdistrikt().getPartiMandater("FI").getResultatData().setStemmer(101); //Flere stemmer enn FRP, men får ikke ujm!
		}

		// Stemmer beregnet på fylkesnivå - disse tallene behøver ikke å
		// stemme helt overens med landstallene. Dette skyldes at prognose
		// på landsnivå kan gi andre resultater enn det som er prognose
		// på fylkesnivå, eller evt. opptalt på fylkesnivå. Kalkulasjonen
		// av utjevningsmandater håndterer dette. Alle distriktsmandatene er fordelt til A og H
		leggTilStemmerOgMandaterIFylket(land, "01", "A", 300, 5);
		leggTilStemmerOgMandaterIFylket(land, "01", "H", 300, 5);
		leggTilStemmerOgMandaterIFylket(land, "01", "FRP", 30, 0);
		leggTilStemmerOgMandaterIFylket(land, "01", "KRF", 30, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "A", 300, 5);
		leggTilStemmerOgMandaterIFylket(land, "02", "H", 300, 5);
		leggTilStemmerOgMandaterIFylket(land, "02", "FRP", 30, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "KRF", 30, 0);
		leggTilStemmerOgMandaterIFylket(land, "03", "A", 300, 5);
		leggTilStemmerOgMandaterIFylket(land, "03", "H", 300, 5);
		leggTilStemmerOgMandaterIFylket(land, "03", "FRP", 30, 0);
		leggTilStemmerOgMandaterIFylket(land, "03", "KRF", 30, 0);
		if (leggTilStemmerForFI) {
			leggTilStemmerOgMandaterIFylket(land, "03", "FI", 101, 0);
		}
	}

	private void leggTilStemmerOgMandaterIFylket(Land land, String fylkeNr, String partikode, int stemmer, int antDistriktsmandater) {
		PartiMandater pm = land.getFylke(fylkeNr).getValgdistrikt().getPartiMandater(partikode);
		pm.getResultatData().setStemmer(stemmer);
		pm.getResultatData().setDistriktsmandater(new Mandater(antDistriktsmandater, 0, 0));

	}

	private Land lagLand(ValgType vt, int antallFylker, String... partikoder) {
		Land land = new Land(vt);
		Valgdistrikt vd = lagValgdistrikt(vt, Konstanter.VALGDISTRIKT_NORGE, partikoder);
		land.setValgdistriktForUtjevningsmandaterOgLandsprognose(vd);

		for (int fnr = 1; fnr <= antallFylker; fnr++) {
			if (fnr == 13) {
				fnr++; // fylke 13 finnes ikke i Norge
				antallFylker++;
			}
			String fylkenr = fnr > 9 ? "" + fnr : "0" + fnr;
			land.getFylker().put(fylkenr, lagFylke(vt, fylkenr, partikoder));
		}
		return land;
	}

	private Fylke lagFylke(ValgType vt, String fylkeNr, String... partikoder) {
		Fylke f = new Fylke();
		f.setNr(fylkeNr);
		f.setValgdistrikt(lagValgdistrikt(vt, fylkeNr, partikoder));
		return f;
	}

	private Valgdistrikt lagValgdistrikt(ValgType vt, String valgdistriktNr, String... partikoder) {

		Set<String> lokalePartier = new TreeSet<>();
		lokalePartier.add("FI");


		Valgdistrikt vd = new Valgdistrikt();
		ValgdistriktId valgdistriktId = new ValgdistriktId();
		valgdistriktId.setNr(valgdistriktNr);
		valgdistriktId.setValgType(vt);
		vd.setId(valgdistriktId);
		int i = 1;
		for (String partikode : partikoder) {
			if (lokalePartier.contains(partikode)) {
				vd.addPartiMandater(new PartiMandater(partikode, partikode, "3", "" + i++, true));
			} else {
				vd.addPartiMandater(new PartiMandater(partikode, partikode, "1", "" + i++, true));
			}
		}
		return vd;
	}

	@Test
	public void beregn_EnkelMenFIFårIkkeUtjevningsmandatFordiDetErEtLokaltParti() throws Exception {


		Land land = lagLand(ValgType.ST, 3, "A", "H", "FRP", "KRF", "FI");

		Map<String, Integer> distriktsmandaterPrFylke = new TreeMap<>();
		distriktsmandaterPrFylke.put("01", 10);
		distriktsmandaterPrFylke.put("02", 10);
		distriktsmandaterPrFylke.put("03", 10);

		leggTilStemmerSlikAtFRPOgKRFFårUtjevningsmandatene(land, true);


		UtjevningsmandatResultat resultat = Utjevningsmandat.beregnOgOppdater(land, distriktsmandaterPrFylke, false);

		Assert.assertEquals("FRP", resultat.getPartiPrFylke().get("01"));
		Assert.assertEquals("FRP", resultat.getPartiPrFylke().get("02"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("03"));
	}

	@Test
	public void beregn_Stortingsvalget2013() throws Exception {
		Land land = lagLand(ValgType.ST, 19, "A", "H", "FRP", "SP", "KRF", "V", "SV", "MDG", "ANDRE");
		Map<String, Integer> distriktsmandaterPrFylke = oppsettDistriktsmandaterPrFylke();

		leggTilStemmerForHeleLandet(land, false);

		UtjevningsmandatResultat resultat = Utjevningsmandat.beregnOgOppdater(land, distriktsmandaterPrFylke, false);

		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("01"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("02"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("03"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("04"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("05"));
		Assert.assertEquals("SP", resultat.getPartiPrFylke().get("06"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("07"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("08"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("09"));
		Assert.assertEquals("A", resultat.getPartiPrFylke().get("10"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("11"));
		Assert.assertEquals("H", resultat.getPartiPrFylke().get("12"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("14"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("15"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("16"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("17"));
		Assert.assertEquals("SP", resultat.getPartiPrFylke().get("18"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("19"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("20"));
	}

	private Map<String, Integer> oppsettDistriktsmandaterPrFylke() {
		Map<String, Integer> distriktsmandaterPrFylke = new TreeMap<>();
		distriktsmandaterPrFylke.put("01", 8);
		distriktsmandaterPrFylke.put("02", 16);
		distriktsmandaterPrFylke.put("03", 18);
		distriktsmandaterPrFylke.put("04", 6);
		distriktsmandaterPrFylke.put("05", 6);
		distriktsmandaterPrFylke.put("06", 8);
		distriktsmandaterPrFylke.put("07", 6);
		distriktsmandaterPrFylke.put("08", 5);
		distriktsmandaterPrFylke.put("09", 3);
		distriktsmandaterPrFylke.put("10", 5);
		distriktsmandaterPrFylke.put("11", 13);
		distriktsmandaterPrFylke.put("12", 15);
		distriktsmandaterPrFylke.put("14", 3);
		distriktsmandaterPrFylke.put("15", 8);
		distriktsmandaterPrFylke.put("16", 9);
		distriktsmandaterPrFylke.put("17", 4);
		distriktsmandaterPrFylke.put("18", 8);
		distriktsmandaterPrFylke.put("19", 5);
		distriktsmandaterPrFylke.put("20", 4);
		return distriktsmandaterPrFylke;
	}

	private void leggTilStemmerForHeleLandet(Land land, boolean modifiser) {
		land.getValgdistrikt().getPartiMandater("A").getResultatData().setStemmer(75);
		land.getValgdistrikt().getPartiMandater("H").getResultatData().setStemmer(108);
		land.getValgdistrikt().getPartiMandater("FRP").getResultatData().setStemmer(0);
		land.getValgdistrikt().getPartiMandater("KRF").getResultatData().setStemmer(9);

		// Stemmer pr parti for hele landet
		land.getValgdistrikt().getPartiMandater("A").getResultatData().setStemmer(874769);
		land.getValgdistrikt().getPartiMandater("FRP").getResultatData().setStemmer(463560);
		land.getValgdistrikt().getPartiMandater("H").getResultatData().setStemmer(760232);
		land.getValgdistrikt().getPartiMandater("KRF").getResultatData().setStemmer(158475);
		land.getValgdistrikt().getPartiMandater("MDG").getResultatData().setStemmer(79152);
		land.getValgdistrikt().getPartiMandater("SP").getResultatData().setStemmer(155357);
		land.getValgdistrikt().getPartiMandater("SV").getResultatData().setStemmer(116021);
		land.getValgdistrikt().getPartiMandater("V").getResultatData().setStemmer(148275);
		land.getValgdistrikt().getPartiMandater("ANDRE").getResultatData().setStemmer(93062);

		// Stemmer pr parti pr fylke
		leggTilStemmerOgMandaterIFylket(land, "01", "A", 54910, 3);
		leggTilStemmerOgMandaterIFylket(land, "01", "FRP", 30801, 2);
		leggTilStemmerOgMandaterIFylket(land, "01", "H", 39703, 3);
		leggTilStemmerOgMandaterIFylket(land, "01", "KRF", 8828, 0);
		leggTilStemmerOgMandaterIFylket(land, "01", "MDG", 3168, 0);
		leggTilStemmerOgMandaterIFylket(land, "01", "SP", 6405, 0);
		leggTilStemmerOgMandaterIFylket(land, "01", "SV", 3668, 0);
		leggTilStemmerOgMandaterIFylket(land, "01", "V", 5723, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "A", 91364, 5);
		leggTilStemmerOgMandaterIFylket(land, "02", "FRP", 54658, 3);
		leggTilStemmerOgMandaterIFylket(land, "02", "H", 108860, 7);
		leggTilStemmerOgMandaterIFylket(land, "02", "KRF", 10377, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "MDG", 9804, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "SP", 8111, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "SV", 11305, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "V", 20217, 1);
		leggTilStemmerOgMandaterIFylket(land, "03", "A", 106001, 6);
		leggTilStemmerOgMandaterIFylket(land, "03", "FRP", 40660, 2);
		leggTilStemmerOgMandaterIFylket(land, "03", "H", 103834, 6);
		leggTilStemmerOgMandaterIFylket(land, "03", "KRF", 9850, 0);
		leggTilStemmerOgMandaterIFylket(land, "03", "MDG", 19356, 1);
		leggTilStemmerOgMandaterIFylket(land, "03", "SP", 2963, 0);
		leggTilStemmerOgMandaterIFylket(land, "03", "SV", 21924, 1);
		leggTilStemmerOgMandaterIFylket(land, "03", "V", 28619, 2);
		leggTilStemmerOgMandaterIFylket(land, "04", "A", 48694, 3);
		leggTilStemmerOgMandaterIFylket(land, "04", "FRP", 15316, 1);
		leggTilStemmerOgMandaterIFylket(land, "04", "H", 20600, 1);
		leggTilStemmerOgMandaterIFylket(land, "04", "KRF", 2871, 0);
		leggTilStemmerOgMandaterIFylket(land, "04", "MDG", 2224, 0);
		leggTilStemmerOgMandaterIFylket(land, "04", "SP", 11483, 1);
		leggTilStemmerOgMandaterIFylket(land, "04", "SV", 4393, 0);
		leggTilStemmerOgMandaterIFylket(land, "04", "V", 3805, 0);
		leggTilStemmerOgMandaterIFylket(land, "05", "A", 44050, 3);
		leggTilStemmerOgMandaterIFylket(land, "05", "FRP", 13683, 1);
		leggTilStemmerOgMandaterIFylket(land, "05", "H", 20537, 1);
		leggTilStemmerOgMandaterIFylket(land, "05", "KRF", 3418, 0);
		leggTilStemmerOgMandaterIFylket(land, "05", "MDG", 2583, 0);
		leggTilStemmerOgMandaterIFylket(land, "05", "SP", 13162, 1);
		leggTilStemmerOgMandaterIFylket(land, "05", "SV", 3165, 0);
		leggTilStemmerOgMandaterIFylket(land, "05", "V", 4248, 0);
		leggTilStemmerOgMandaterIFylket(land, "06", "A", 47572, 3);
		leggTilStemmerOgMandaterIFylket(land, "06", "FRP", 27854, 2);
		leggTilStemmerOgMandaterIFylket(land, "06", "H", 43515, 3);
		leggTilStemmerOgMandaterIFylket(land, "06", "KRF", 4863, 0);
		leggTilStemmerOgMandaterIFylket(land, "06", "MDG", 3345, 0);
		leggTilStemmerOgMandaterIFylket(land, "06", "SP", 9110, 0);
		leggTilStemmerOgMandaterIFylket(land, "06", "SV", 4094, 0);
		leggTilStemmerOgMandaterIFylket(land, "06", "V", 6913, 0);
		leggTilStemmerOgMandaterIFylket(land, "07", "A", 40869, 2);
		leggTilStemmerOgMandaterIFylket(land, "07", "FRP", 26977, 2);
		leggTilStemmerOgMandaterIFylket(land, "07", "H", 41357, 2);
		leggTilStemmerOgMandaterIFylket(land, "07", "KRF", 6735, 0);
		leggTilStemmerOgMandaterIFylket(land, "07", "MDG", 3407, 0);
		leggTilStemmerOgMandaterIFylket(land, "07", "SP", 4084, 0);
		leggTilStemmerOgMandaterIFylket(land, "07", "SV", 5266, 0);
		leggTilStemmerOgMandaterIFylket(land, "07", "V", 6228, 0);
		leggTilStemmerOgMandaterIFylket(land, "08", "A", 35963, 3);
		leggTilStemmerOgMandaterIFylket(land, "08", "FRP", 18564, 1);
		leggTilStemmerOgMandaterIFylket(land, "08", "H", 21300, 1);
		leggTilStemmerOgMandaterIFylket(land, "08", "KRF", 6610, 0);
		leggTilStemmerOgMandaterIFylket(land, "08", "MDG", 2116, 0);
		leggTilStemmerOgMandaterIFylket(land, "08", "SP", 4360, 0);
		leggTilStemmerOgMandaterIFylket(land, "08", "SV", 3192, 0);
		leggTilStemmerOgMandaterIFylket(land, "08", "V", 3393, 0);
		leggTilStemmerOgMandaterIFylket(land, "09", "A", 17623, 1);
		leggTilStemmerOgMandaterIFylket(land, "09", "FRP", 11278, 1);
		leggTilStemmerOgMandaterIFylket(land, "09", "H", 16303, 1);
		leggTilStemmerOgMandaterIFylket(land, "09", "KRF", 7019, 0);
		leggTilStemmerOgMandaterIFylket(land, "09", "MDG", 1242, 0);
		leggTilStemmerOgMandaterIFylket(land, "09", "SP", 2815, 0);
		leggTilStemmerOgMandaterIFylket(land, "09", "SV", 1652, 0);
		leggTilStemmerOgMandaterIFylket(land, "09", "V", 3033, 0);
		leggTilStemmerOgMandaterIFylket(land, "10", "A", 23227, 1);
		leggTilStemmerOgMandaterIFylket(land, "10", "FRP", 17863, 1);
		leggTilStemmerOgMandaterIFylket(land, "10", "H", 26818, 2);
		leggTilStemmerOgMandaterIFylket(land, "10", "KRF", 13536, 1);
		leggTilStemmerOgMandaterIFylket(land, "10", "MDG", 2196, 0);
		leggTilStemmerOgMandaterIFylket(land, "10", "SP", 2962, 0);
		leggTilStemmerOgMandaterIFylket(land, "10", "SV", 2568, 0);
		leggTilStemmerOgMandaterIFylket(land, "10", "V", 4205, 0);
		leggTilStemmerOgMandaterIFylket(land, "11", "A", 54462, 3);
		leggTilStemmerOgMandaterIFylket(land, "11", "FRP", 45082, 3);
		leggTilStemmerOgMandaterIFylket(land, "11", "H", 72470, 4);
		leggTilStemmerOgMandaterIFylket(land, "11", "KRF", 25585, 2);
		leggTilStemmerOgMandaterIFylket(land, "11", "MDG", 5267, 0);
		leggTilStemmerOgMandaterIFylket(land, "11", "SP", 12621, 1);
		leggTilStemmerOgMandaterIFylket(land, "11", "SV", 7908, 0);
		leggTilStemmerOgMandaterIFylket(land, "11", "V", 10827, 0);
		leggTilStemmerOgMandaterIFylket(land, "12", "A", 71216, 4);
		leggTilStemmerOgMandaterIFylket(land, "12", "FRP", 43357, 2);
		leggTilStemmerOgMandaterIFylket(land, "12", "H", 89682, 5);
		leggTilStemmerOgMandaterIFylket(land, "12", "KRF", 22114, 1);
		leggTilStemmerOgMandaterIFylket(land, "12", "MDG", 9171, 0);
		leggTilStemmerOgMandaterIFylket(land, "12", "SP", 12490, 1);
		leggTilStemmerOgMandaterIFylket(land, "12", "SV", 14143, 1);
		leggTilStemmerOgMandaterIFylket(land, "12", "V", 16614, 1);
		leggTilStemmerOgMandaterIFylket(land, "14", "A", 17183, 1);
		leggTilStemmerOgMandaterIFylket(land, "14", "FRP", 6608, 0);
		leggTilStemmerOgMandaterIFylket(land, "14", "H", 11635, 1);
		leggTilStemmerOgMandaterIFylket(land, "14", "KRF", 4952, 0);
		leggTilStemmerOgMandaterIFylket(land, "14", "MDG", 1032, 0);
		leggTilStemmerOgMandaterIFylket(land, "14", "SP", 12619, 1);
		leggTilStemmerOgMandaterIFylket(land, "14", "SV", 2076, 0);
		leggTilStemmerOgMandaterIFylket(land, "14", "V", 3883, 0);
		leggTilStemmerOgMandaterIFylket(land, "15", "A", 36048, 2);
		leggTilStemmerOgMandaterIFylket(land, "15", "FRP", 28746, 2);
		leggTilStemmerOgMandaterIFylket(land, "15", "H", 37594, 2);
		leggTilStemmerOgMandaterIFylket(land, "15", "KRF", 12786, 1);
		leggTilStemmerOgMandaterIFylket(land, "15", "MDG", 1963, 0);
		leggTilStemmerOgMandaterIFylket(land, "15", "SP", 11749, 1);
		leggTilStemmerOgMandaterIFylket(land, "15", "SV", 3532, 0);
		leggTilStemmerOgMandaterIFylket(land, "15", "V", 7965, 0);
		leggTilStemmerOgMandaterIFylket(land, "16", "A", 64351, 4);
		leggTilStemmerOgMandaterIFylket(land, "16", "FRP", 23871, 2);
		leggTilStemmerOgMandaterIFylket(land, "16", "H", 38930, 2);
		leggTilStemmerOgMandaterIFylket(land, "16", "KRF", 6562, 0);
		leggTilStemmerOgMandaterIFylket(land, "16", "MDG", 5540, 0);
		leggTilStemmerOgMandaterIFylket(land, "16", "SP", 11351, 1);
		leggTilStemmerOgMandaterIFylket(land, "16", "SV", 9992, 0);
		leggTilStemmerOgMandaterIFylket(land, "16", "V", 9460, 0);
		leggTilStemmerOgMandaterIFylket(land, "17", "A", 32054, 2);
		leggTilStemmerOgMandaterIFylket(land, "17", "FRP", 9869, 0);
		leggTilStemmerOgMandaterIFylket(land, "17", "H", 11128, 1);
		leggTilStemmerOgMandaterIFylket(land, "17", "KRF", 2707, 0);
		leggTilStemmerOgMandaterIFylket(land, "17", "MDG", 1051, 0);
		leggTilStemmerOgMandaterIFylket(land, "17", "SP", 12796, 1);
		leggTilStemmerOgMandaterIFylket(land, "17", "SV", 2596, 0);
		leggTilStemmerOgMandaterIFylket(land, "17", "V", 3158, 0);
		leggTilStemmerOgMandaterIFylket(land, "18", "A", 46743, 4);
		leggTilStemmerOgMandaterIFylket(land, "18", "FRP", 25020, 2);
		leggTilStemmerOgMandaterIFylket(land, "18", "H", 28271, 2);
		leggTilStemmerOgMandaterIFylket(land, "18", "KRF", 4886, 0);
		leggTilStemmerOgMandaterIFylket(land, "18", "MDG", 2653, 0);
		leggTilStemmerOgMandaterIFylket(land, "18", "SP", 9237, 0);
		leggTilStemmerOgMandaterIFylket(land, "18", "SV", 6907, 0);
		leggTilStemmerOgMandaterIFylket(land, "18", "V", 4938, 0);
		leggTilStemmerOgMandaterIFylket(land, "19", "A", 27436, 2);
		leggTilStemmerOgMandaterIFylket(land, "19", "FRP", 17315, 1);
		leggTilStemmerOgMandaterIFylket(land, "19", "H", 19663, 2);
		leggTilStemmerOgMandaterIFylket(land, "19", "KRF", 3659, 0);
		leggTilStemmerOgMandaterIFylket(land, "19", "MDG", 2190, 0);
		leggTilStemmerOgMandaterIFylket(land, "19", "SP", 5636, 0);
		leggTilStemmerOgMandaterIFylket(land, "19", "SV", 5688, 0);
		leggTilStemmerOgMandaterIFylket(land, "19", "V", 3687, 0);
		leggTilStemmerOgMandaterIFylket(land, "20", "A", 15003, 2);
		leggTilStemmerOgMandaterIFylket(land, "20", "FRP", 6038, 1);
		leggTilStemmerOgMandaterIFylket(land, "20", "H", 8032, 1);
		leggTilStemmerOgMandaterIFylket(land, "20", "KRF", 1117, 0);
		leggTilStemmerOgMandaterIFylket(land, "20", "MDG", 844, 0);
		leggTilStemmerOgMandaterIFylket(land, "20", "SP", 1403, 0);
		leggTilStemmerOgMandaterIFylket(land, "20", "SV", 1952, 0);
		leggTilStemmerOgMandaterIFylket(land, "20", "V", 1359, 0);

		// Legg til summen av alle partier som ikke får noen mandater overhodet i dette valget
		leggTilStemmerOgMandaterIFylket(land, "01", "ANDRE", 4951, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "ANDRE", 7820, 0);
		leggTilStemmerOgMandaterIFylket(land, "03", "ANDRE", 16634, 0);
		leggTilStemmerOgMandaterIFylket(land, "04", "ANDRE", 4002, 0);
		leggTilStemmerOgMandaterIFylket(land, "05", "ANDRE", 3051, 0);
		leggTilStemmerOgMandaterIFylket(land, "06", "ANDRE", 3362, 0);
		leggTilStemmerOgMandaterIFylket(land, "07", "ANDRE", 3827, 0);
		leggTilStemmerOgMandaterIFylket(land, "08", "ANDRE", 2835, 0);
		leggTilStemmerOgMandaterIFylket(land, "09", "ANDRE", 2250, 0);
		leggTilStemmerOgMandaterIFylket(land, "10", "ANDRE", 4609, 0);
		leggTilStemmerOgMandaterIFylket(land, "11", "ANDRE", 7219, 0);
		leggTilStemmerOgMandaterIFylket(land, "12", "ANDRE", 9006, 0);
		leggTilStemmerOgMandaterIFylket(land, "14", "ANDRE", 1437, 0);
		leggTilStemmerOgMandaterIFylket(land, "15", "ANDRE", 3499, 0);
		leggTilStemmerOgMandaterIFylket(land, "16", "ANDRE", 6086, 0);
		leggTilStemmerOgMandaterIFylket(land, "17", "ANDRE", 1484, 0);
		leggTilStemmerOgMandaterIFylket(land, "18", "ANDRE", 5303, 0);
		leggTilStemmerOgMandaterIFylket(land, "19", "ANDRE", 3486, 0);
		leggTilStemmerOgMandaterIFylket(land, "20", "ANDRE", 2201, 0);

		if (modifiser) {
			// Fjerner stemmene for SV fra Nord-Trøndelag
//            land.getValgdistrikt().getPartiMandater("V").setStemmer(116021 - 3158);
			land.getFylke("17").getValgdistrikt().getPartiMandater("V").getResultatData().setStemmer(0); // fjerner 3158 stemmer
			// Dette er de 2 siste fylkene som får utjevningsmandater - vi gjør den miste endringen vi kan som gjør at
			// ingen partier endrer antall utjevningsmandater som de skal få
			land.getFylke("14").getValgdistrikt().getPartiMandater("V").getResultatData().setStemmer(3883 + 1000); // legger til 1000 stemmer
			land.getFylke("20").getValgdistrikt().getPartiMandater("V").getResultatData().setStemmer(1359 + 500); // legger til 500 stemmer
		}


	}

	@Test
	public void beregn_Stortingsvalget2013_Mod_DekkesIkkeAvValgloven() throws Exception {
		Land land = lagLand(ValgType.ST, 19, "A", "H", "FRP", "SP", "KRF", "V", "SV", "MDG", "ANDRE");
		land.getFylke("17").getValgdistrikt().getPartiMandater().remove("V"); // Later som V ikke stiller i Nord-Trøndelag
		Map<String, Integer> distriktsmandaterPrFylke = oppsettDistriktsmandaterPrFylke();

		leggTilStemmerForHeleLandet(land, true); // Nuller Vs stemmer i Nord-Trøndelag, men legger til totalt 1500 V-stemmer i Sogn og Fjordane og Finnmark

		UtjevningsmandatResultat resultat = Utjevningsmandat.beregnOgOppdater(land, distriktsmandaterPrFylke, false);

		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("01"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("02"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("03"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("04"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("05"));
		Assert.assertEquals("SP", resultat.getPartiPrFylke().get("06"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("07"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("08"));
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("09"));
		Assert.assertEquals("A", resultat.getPartiPrFylke().get("10"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("11"));
		Assert.assertEquals("H", resultat.getPartiPrFylke().get("12"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("14"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("15"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("16"));
		Assert.assertEquals("V", resultat.getPartiPrFylke().get("17")); // V får utjevningsmandatet her, men stiller ikke liste!!!!
		Assert.assertEquals("SP", resultat.getPartiPrFylke().get("18"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("19"));
		Assert.assertEquals("SV", resultat.getPartiPrFylke().get("20"));
	}

	@Test
	public void beregn_TilfelleSomIkkeDekkesAvValgloven() throws Exception {
		Land land = lagLand(ValgType.ST, 3, "A", "H", "FRP", "KRF");
		land.getFylke("02").getValgdistrikt().getPartiMandater().remove("KRF"); // KRF stiller ikke i Akershus
		land.getFylke("01").getValgdistrikt().getPartiMandater().remove("KRF"); // KRF stiller ikke i Østfold


		Map<String, Integer> distriktsmandaterPrFylke = new TreeMap<>();
		distriktsmandaterPrFylke.put("01", 25);
		distriktsmandaterPrFylke.put("02", 5);
		distriktsmandaterPrFylke.put("03", 5);

		leggTilStemmerSlikAtKRFFårUtjevningsmandatMenIkkeIOslo(land);

		UtjevningsmandatResultat resultat = Utjevningsmandat.beregnOgOppdater(land, distriktsmandaterPrFylke, false);
		// Utjevningsmandatet i Akershus går til KRF, men KRF stiller ikke liste der!!
		Assert.assertEquals("KRF", resultat.getPartiPrFylke().get("02"));
	}

	private void leggTilStemmerSlikAtKRFFårUtjevningsmandatMenIkkeIOslo(Land land) {
		// Stemmer beregnet på landsnivå - KRF er akkurat under sperregrensen (3.99995%)
		land.getValgdistrikt().getPartiMandater("A").getResultatData().setStemmer(75);
		land.getValgdistrikt().getPartiMandater("H").getResultatData().setStemmer(108);
		land.getValgdistrikt().getPartiMandater("FRP").getResultatData().setStemmer(0);
		land.getValgdistrikt().getPartiMandater("KRF").getResultatData().setStemmer(9);

		// Stemmer beregnet på fylkesnivå - disse tallene behøver ikke å
		// stemme helt overens med landstallene. Dette skyldes at prognose
		// på landsnivå kan gi andre resultater enn det som er prognose
		// på fylkesnivå, eller evt. opptalt på fylkesnivå. Kalkulasjonen
		// av utjevningsmandater håndterer dette. Alle distriktsmandatene er fordelt til A og H
		leggTilStemmerOgMandaterIFylket(land, "01", "A", 24, 10);
		leggTilStemmerOgMandaterIFylket(land, "01", "H", 37, 15);
		leggTilStemmerOgMandaterIFylket(land, "01", "FRP", 0, 0);
		leggTilStemmerOgMandaterIFylket(land, "01", "KRF", 0, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "A", 33, 2);
		leggTilStemmerOgMandaterIFylket(land, "02", "H", 44, 3);
		leggTilStemmerOgMandaterIFylket(land, "02", "FRP", 0, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "KRF", 0, 0);
		leggTilStemmerOgMandaterIFylket(land, "03", "A", 18, 2);
		leggTilStemmerOgMandaterIFylket(land, "03", "H", 27, 2);
		leggTilStemmerOgMandaterIFylket(land, "03", "FRP", 0, 0);
		leggTilStemmerOgMandaterIFylket(land, "03", "KRF", 9, 1);
	}

	@Test
	public void beregn_UnderSperregrense() throws Exception {


		Land land = lagLand(ValgType.ST, 3, "A", "H", "FRP", "KRF");

		Map<String, Integer> distriktsmandaterPrFylke = new TreeMap<>();
		distriktsmandaterPrFylke.put("01", 10);
		distriktsmandaterPrFylke.put("02", 10);
		distriktsmandaterPrFylke.put("03", 10);

		leggTilStemmerSlikAtKRFAkkuratFallerUnderSperregrense(land);


		UtjevningsmandatResultat resultat = Utjevningsmandat.beregnOgOppdater(land, distriktsmandaterPrFylke, false);

		Assert.assertEquals("FRP", resultat.getPartiPrFylke().get("01"));
		Assert.assertEquals("FRP", resultat.getPartiPrFylke().get("02"));
		Assert.assertEquals("A", resultat.getPartiPrFylke().get("03"));
	}

	private void leggTilStemmerSlikAtKRFAkkuratFallerUnderSperregrense(Land land) {
		// Stemmer beregnet på landsnivå - KRF er akkurat under sperregrensen (3.99995%)
		land.getValgdistrikt().getPartiMandater("A").getResultatData().setStemmer(900000);
		land.getValgdistrikt().getPartiMandater("H").getResultatData().setStemmer(900000);
		land.getValgdistrikt().getPartiMandater("FRP").getResultatData().setStemmer(120001);
		land.getValgdistrikt().getPartiMandater("KRF").getResultatData().setStemmer(79999);

		// Stemmer beregnet på fylkesnivå - disse tallene behøver ikke å
		// stemme helt overens med landstallene. Dette skyldes at prognose
		// på landsnivå kan gi andre resultater enn det som er prognose
		// på fylkesnivå, eller evt. opptalt på fylkesnivå. Kalkulasjonen
		// av utjevningsmandater håndterer dette. Alle distriktsmandatene er fordelt til A og H
		leggTilStemmerOgMandaterIFylket(land, "01", "A", 300000, 5);
		leggTilStemmerOgMandaterIFylket(land, "01", "H", 300000, 5);
		leggTilStemmerOgMandaterIFylket(land, "01", "FRP", 30000, 0);
		leggTilStemmerOgMandaterIFylket(land, "01", "KRF", 30000, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "A", 300000, 5);
		leggTilStemmerOgMandaterIFylket(land, "02", "H", 300000, 5);
		leggTilStemmerOgMandaterIFylket(land, "02", "FRP", 30000, 0);
		leggTilStemmerOgMandaterIFylket(land, "02", "KRF", 30000, 0);
		leggTilStemmerOgMandaterIFylket(land, "03", "A", 300000, 5);
		leggTilStemmerOgMandaterIFylket(land, "03", "H", 300000, 5);
		leggTilStemmerOgMandaterIFylket(land, "03", "FRP", 30000, 0);
		leggTilStemmerOgMandaterIFylket(land, "03", "KRF", 30000, 0);
	}

}
