package it.polimi.ingsw.gc14.Model.Cards.TribeCards.Characters;

import it.polimi.ingsw.gc14.Model.Cards.TribeCards.CharacterType;
import it.polimi.ingsw.gc14.Model.Player;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.*;

class BuilderTest {

    @Test
    void getReductionValue() {
        Builder b = new Builder(1, 2 , 3);

        assertEquals(2, b.getReductionValue());
    }

    @Test
    void getPrestigeValue() {
        Builder b = new Builder(1, 2 , 3);
        assertEquals(3, b.getPrestigeValue());
    }

    @Test
    void testToString() {
        Builder b = new Builder(1, 2 , 3);
        String s = b.toString();

        assertNotNull(s);
        assertTrue(s.contains(CharacterType.BUILDER.toString()));
        assertTrue(s.contains("Reduction Value: 2"));
        assertTrue(s.contains("Prestige Value: 3"));
    }

    @Test
    void testClone() {
        Builder b = new Builder(1, 2, 3, 4);
        Builder clone = (Builder) b.clone();

        assertNotNull(clone);
        assertNotSame(b, clone);
        assertEquals(b.getEra(), clone.getEra());
        assertEquals(b.getType(), clone.getType());
        assertEquals(b.getReductionValue(), clone.getReductionValue());
        assertEquals(b.getPrestigeValue(), clone.getPrestigeValue());
        assertEquals(b.getNMin(), clone.getNMin());
    }

    @Test
    void insert() {
        Player p = new Player("test");
        Builder b = new Builder(1, 2, 3);

        assertEquals(0, p.builders.size());

        b.insert(p);

        assertEquals(1, p.builders.size());
        assertTrue(p.builders.contains(b));

        Builder b2 = new Builder(1, 4, 5);
        b2.insert(p);

        assertEquals(2, p.builders.size());
        assertTrue(p.builders.contains(b2));
    }

    @Test
    void constructorTest() {
        Builder b = new Builder(1, 2, 3);

        assertEquals(1, b.getEra());
        assertEquals(CharacterType.BUILDER, b.getType());
        assertEquals(2, b.getReductionValue());
        assertEquals(3, b.getPrestigeValue());
        assertEquals(0, b.getNMin());
        assertFalse(b.IsEventCard());
    }

    @Test
    void constructorWithNMinTest() {
        // Correct case
        Builder b = new Builder(1, 2, 3, 4);

        assertEquals(1, b.getEra());
        assertEquals(CharacterType.BUILDER, b.getType());
        assertEquals(2, b.getReductionValue());
        assertEquals(3, b.getPrestigeValue());
        assertEquals(4, b.getNMin());
        assertFalse(b.IsEventCard());

        // Wrong reductionValue
        assertThrows(IllegalArgumentException.class, () -> {new Builder(1, -1, 3, 4);});

        // Wrong prestigeValue
        assertThrows(IllegalArgumentException.class, () -> {new Builder(1, 2, -1, 4);});
    }

    @Test
    void negativeReductionValue() {
        assertThrows(IllegalArgumentException.class, () -> {
            new Builder(1, -1, 3);
        });
    }

    @Test
    void negativePrestigeValue() {
        assertThrows(IllegalArgumentException.class, () -> {
            new Builder(1, 2, -3);
        });
    }
}