package org.luxons.sevenwonders.game.test;

import java.util.ArrayList;
import java.util.List;

import org.luxons.sevenwonders.game.Player;
import org.luxons.sevenwonders.game.Settings;
import org.luxons.sevenwonders.game.api.Table;
import org.luxons.sevenwonders.game.boards.Board;
import org.luxons.sevenwonders.game.boards.Science;
import org.luxons.sevenwonders.game.boards.ScienceType;
import org.luxons.sevenwonders.game.cards.Card;
import org.luxons.sevenwonders.game.cards.Color;
import org.luxons.sevenwonders.game.cards.Requirements;
import org.luxons.sevenwonders.game.effects.ScienceProgress;
import org.luxons.sevenwonders.game.resources.BoughtResources;
import org.luxons.sevenwonders.game.resources.Production;
import org.luxons.sevenwonders.game.resources.Provider;
import org.luxons.sevenwonders.game.resources.ResourceType;
import org.luxons.sevenwonders.game.resources.Resources;
import org.luxons.sevenwonders.game.wonders.Wonder;

public class TestUtils {

    public static Table createTable(int nbPlayers) {
        return new Table(createBoards(nbPlayers));
    }

    public static List<Board> createBoards(int count) {
        List<Board> boards = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            boards.add(createBoard(ResourceType.WOOD));
        }
        return boards;
    }

    public static List<Player> createPlayers(int count) {
        List<Player> players = new ArrayList<>(count);
        for (int i = 0; i < count; i++) {
            String userName = "testUser" + i;
            String displayName = "Test User " + i;
            Player player = new Player(displayName, userName);
            players.add(player);
        }
        return players;
    }

    public static Board createBoard(ResourceType initialResource) {
        Settings settings = new Settings();
        Wonder wonder = new Wonder("Test Wonder " + initialResource.getSymbol(), initialResource);

        String userName = "testUser" + initialResource.getSymbol();
        String displayName = "Test User " + initialResource.getSymbol();
        Player player = new Player(displayName, userName);

        return new Board(wonder, player, settings);
    }

    public static Board createBoard(ResourceType initialResource, ResourceType... production) {
        Board board = createBoard(initialResource);
        board.getProduction().addAll(createFixedProduction(production));
        return board;
    }

    public static Board createBoard(ResourceType initialResource, int gold, ResourceType... production) {
        Board board = createBoard(initialResource, production);
        board.setGold(gold);
        return board;
    }

    public static Wonder createWonder() {
        return createWonder(ResourceType.WOOD);
    }

    public static Wonder createWonder(ResourceType initialResource) {
        return new Wonder("Test Wonder " + initialResource.getSymbol(), initialResource);
    }

    public static Production createFixedProduction(ResourceType... producedTypes) {
        Production production = new Production();
        Resources fixedProducedResources = production.getFixedResources();
        fixedProducedResources.addAll(createResources(producedTypes));
        return production;
    }

    public static Resources createResources(ResourceType... types) {
        Resources resources = new Resources();
        for (ResourceType producedType : types) {
            resources.add(producedType, 1);
        }
        return resources;
    }

    public static BoughtResources createBoughtResources(Provider provider, ResourceType... resources) {
        BoughtResources boughtResources = new BoughtResources();
        boughtResources.setProvider(provider);
        boughtResources.setResources(TestUtils.createResources(resources));
        return boughtResources;
    }

    public static List<Card> createSampleCards(int fromIndex, int nbCards) {
        List<Card> sampleCards = new ArrayList<>();
        for (int i = fromIndex; i < fromIndex + nbCards; i++) {
            sampleCards.add(new Card("Test Card " + i, Color.BLUE, new Requirements(), null, null, null, null));
        }
        return sampleCards;
    }

    public static ScienceProgress createScienceProgress(int compasses, int wheels, int tablets, int jokers) {
        ScienceProgress progress = new ScienceProgress();
        progress.setScience(TestUtils.createScience(compasses, wheels, tablets, jokers));
        return progress;
    }

    public static Science createScience(int compasses, int wheels, int tablets, int jokers) {
        Science science = new Science();
        if (compasses > 0) {
            science.add(ScienceType.COMPASS, compasses);
        }
        if (wheels > 0) {
            science.add(ScienceType.WHEEL, wheels);
        }
        if (tablets > 0) {
            science.add(ScienceType.TABLET, tablets);
        }
        if (jokers > 0) {
            science.addJoker(jokers);
        }
        return science;
    }
}

@@ -943,16 +943,73 @@
 .Wonder;
+%0Aimport org.luxons.sevenwonders.game.wonders.WonderStage;
 %0A%0Apublic
@@ -1915,65 +1915,21 @@
 r = 
-new Wonder(%22Test Wonder %22 + initialResource.getSymbol(), 
+createWonder(
 init
@@ -2840,32 +2840,332 @@
 tialResource) %7B%0A
+        WonderStage stage1 = new WonderStage();%0A        stage1.setRequirements(new Requirements());%0A        WonderStage stage2 = new WonderStage();%0A        stage1.setRequirements(new Requirements());%0A        WonderStage stage3 = new WonderStage();%0A        stage1.setRequirements(new Requirements());%0A
         return n
@@ -3231,24 +3231,48 @@
 tialResource
+, stage1, stage2, stage3
 );%0A    %7D%0A%0A  
@@ -4388,16 +4388,162 @@
 rds.add(
+createCard(i, Color.BLUE));%0A        %7D%0A        return sampleCards;%0A    %7D%0A%0A    public static Card createCard(int num, Color color) %7B%0A        return 
 new Card
@@ -4558,29 +4558,26 @@
 ard %22 + 
-i, C
+num, c
 olor
-.BLUE
 , new Re
@@ -4617,47 +4617,8 @@
 ull)
-);%0A        %7D%0A        return sampleCards
 ;%0A  

Add minimal stages in test wonders