package no.valg.valgnatt.backend.mandatberegning;

import no.valg.valgnatt.database.domene.ValgType;
import no.valg.valgnatt.database.geografi.Fylke;
import no.valg.valgnatt.database.geografi.Kommune;
import no.valg.valgnatt.database.geografi.Land;
import no.valg.valgnatt.database.geografi.Område;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.HashMap;

import static org.junit.Assert.*;
import static org.mockito.Mockito.when;

@RunWith(MockitoJUnitRunner.class)
public class MandatBeregningArgumenterTest {
    
    @Mock
    private Område område;
    
    @Mock
    private Land land;
    
    @Test
    public void forsøkPrognose_gittOpptaltberegning_returnererFasle() {
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(område, true);
        
        assertFalse(mandatBeregningArgumenter.forsøkPrognose());
    }

    @Test
    public void forsøkPrognose_gittIkkeOpptaltberegningOgST_returnererTrue() {
        when(område.getValgType()).thenReturn(ValgType.ST);
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(område, false);

        assertTrue(mandatBeregningArgumenter.forsøkPrognose());
    }

    @Test
    public void forsøkPrognose_gittIkkeOpptaltberegningOgFY_returnererTrue() {
        when(område.getValgType()).thenReturn(ValgType.FY);
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(område, false);

        assertTrue(mandatBeregningArgumenter.forsøkPrognose());
    }

    @Test
    public void forsøkPrognose_gittIkkeOpptaltberegningOgPrognosekommune_returnererTrue() {
        when(område.getValgType()).thenReturn(ValgType.KO);
        when(område.getNr()).thenReturn("0301");
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(område, false);

        assertTrue(mandatBeregningArgumenter.forsøkPrognose());
    }

    @Test
    public void forsøkPrognose_gittIkkeOpptaltberegningOgIkkePrognosekommune_returnererFalse() {
        when(område.getValgType()).thenReturn(ValgType.KO);
        when(område.getNr()).thenReturn("0701");
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(område, false);

        assertFalse(mandatBeregningArgumenter.forsøkPrognose());
    }

    @Test
    public void erDistriktsmandatBeregning_gittKommune_returnererFalse() {
        Kommune kommune = new Kommune("0701", "Horten", false, false);
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(kommune, false);
        assertFalse(mandatBeregningArgumenter.erUtjevningsmandatBeregning());
    }

    @Test
    public void erDistriktsmandatBeregning_gittLand_returnererTrue() {
        Land land = new Land(ValgType.KO);
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(land, false);
        assertTrue(mandatBeregningArgumenter.erUtjevningsmandatBeregning());
    }

    @Test
    public void equals_gittTilsvarendeObjekt_returnererTrue() {
        Kommune kommune1 = new Kommune("0701", "Horten", false, false);
        MandatBeregningArgumenter mandatBeregningArgumenter1 = new MandatBeregningArgumenter(kommune1, false);
        Kommune kommune2 = new Kommune("0701", "Horten", false, false);
        MandatBeregningArgumenter mandatBeregningArgumenter2 = new MandatBeregningArgumenter(kommune2, false);

        assertEquals(mandatBeregningArgumenter1, mandatBeregningArgumenter2);
    }

    @Test
    public void id_gittOmrådeOgOpptaltBeregning_returnererId() {
        when(område.getValgType()).thenReturn(ValgType.KO);
        when(område.getNr()).thenReturn("0301");
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(område, false);
        
        assertEquals("KO-0301-false", mandatBeregningArgumenter.id());
    }

    @Test
    public void hashCode_gittOmrådeOgOpptaltBeregning_returnererHashCode() {
        when(område.getValgType()).thenReturn(ValgType.KO);
        when(område.getNr()).thenReturn("0301");
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(område, false);

        assertEquals(-1330733725, mandatBeregningArgumenter.hashCode());
    }

    @Test
    public void compareTo_GittLandOgFylke_girFylkeFørst() {
        Land land = new Land(ValgType.FY);
        MandatBeregningArgumenter mandatBeregningArgumenterLand = new MandatBeregningArgumenter(land, false);
        Fylke fylke = new Fylke();
        MandatBeregningArgumenter mandatBeregningArgumenterFylke = new MandatBeregningArgumenter(fylke, false);
        
        assertTrue(mandatBeregningArgumenterFylke.compareTo(mandatBeregningArgumenterLand) < 0);
    }

    @Test
    public void getAntallMandaterSTValg_gittFylkesnummer_returnererAntallMandater() {
        HashMap<String, Integer> mandaterPrFylkeST = new HashMap<>();
        int antallMandater = 17;
        String fylkesnummer = "12";
        when(område.getNr()).thenReturn(fylkesnummer);
        mandaterPrFylkeST.put(fylkesnummer, antallMandater);
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(område, false, mandaterPrFylkeST);
        
        assertEquals(antallMandater, mandatBeregningArgumenter.getAntallMandaterSTValg(område));
    }

    @Test
    public void getAntallMandaterSTValg_gittUkjentFylkesnummer_returnerer0() {
        HashMap<String, Integer> mandaterPrFylkeST = new HashMap<>();
        int antallMandater = 17;
        when(område.getNr()).thenReturn("12");
        mandaterPrFylkeST.put("03", antallMandater);
        MandatBeregningArgumenter mandatBeregningArgumenter = new MandatBeregningArgumenter(område, false, mandaterPrFylkeST);

        assertEquals(0, mandatBeregningArgumenter.getAntallMandaterSTValg(område));
    }
}
