import java.util.ArrayList;

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

public class BlackjackInitialTester
{
    private static final double MONEY_TOLERANCE = 0.009;
    
    @Test
    public void testGetPlayersMoney()
    {
        TestShoe.cards = BlackjackInitialTester.getCardListInReverseOrder(new int[]
                {8, BlackjackCard.KING_VALUE, BlackjackCard.ACE_VALUE, 10});

        Blackjack bj = new Blackjack(1000);

        assertEquals(1000, bj.getPlayersMoney(), MONEY_TOLERANCE);
    }

    @Test
    public void testPlaceBetAndDealCards()
    {
        TestShoe.cards = BlackjackInitialTester.getCardListInReverseOrder(new int[]
                {8, BlackjackCard.KING_VALUE, BlackjackCard.ACE_VALUE, 10});

        Blackjack bj = new Blackjack(1000);

        bj.placeBetAndDealCards(10);
        
        assertEquals(990, bj.getPlayersMoney(), MONEY_TOLERANCE);
        assertEquals(10, bj.getPlayersBet(), MONEY_TOLERANCE);

        int[] expectedPlayersHandCardValues = {8, BlackjackCard.ACE_VALUE};
        assertTrue(BlackjackInitialTester.cardValuesMatchExpected(
                expectedPlayersHandCardValues, bj.getPlayersHand().getCards()));

        int[] expectedDealersHandCardValues = {BlackjackCard.KING_VALUE, 10};
        assertTrue(BlackjackInitialTester.cardValuesMatchExpected(
                expectedDealersHandCardValues, bj.getDealersHand().getCards()));
    }
    
    /*
     * Returns true if the card values match the expected values (in order), false otherwise.
     * Note: size must match expected length.
     */
    public static boolean cardValuesMatchExpected(int[] expectedCardValues,
            ArrayList<BlackjackCard> actualCards)
    {
        if(actualCards.size() != expectedCardValues.length)
            return false;
        
        for(int i = 0; i < expectedCardValues.length; i++)
            if(actualCards.get(i).getValue() != expectedCardValues[i])
                return false;
        
        return true;
    }
    
    /*
     * Returns a list of cards with the specified values and random suits
     * in reverse order.
     */
    public static ArrayList<BlackjackCard> getCardListInReverseOrder(int[] values)
    {
        String[] suits = {"H", "D", "S", "C"};
        
        ArrayList<BlackjackCard> cardsList = new ArrayList<BlackjackCard>();
        
        for(int value : values)
        {
            String suit = suits[(int) (Math.random() * suits.length)];
            cardsList.add(0, new BlackjackCard(value, suit));
        }
        
        return cardsList;
    }
}
