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

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.util.ArrayList;

import org.junit.jupiter.api.Test;

public class BlackjackUIAutomatedTester
{
    @Test
    public void testPlayHand1()
    {
        TestShoe.cards = new ArrayList<BlackjackCard>();
        TestShoe.cards.add(new BlackjackCard(7, "S"));
        TestShoe.cards.add(new BlackjackCard(8, "H"));
        TestShoe.cards.add(new BlackjackCard(10, "D"));
        TestShoe.cards.add(new BlackjackCard(10, "S"));
        
        String input = "10\nn\n";
        ByteArrayInputStream testIn = new ByteArrayInputStream(input.getBytes());
        System.setIn(testIn);
        
        ByteArrayOutputStream testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
        
        BlackjackUI bjui = new BlackjackUI();
        
        bjui.playHand();
        
        String expectedOut =
                "\nBet: $\n"
                + "Dealer: 10D\n"
                + "Player: 10S 8H (18)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 10D 7S (17)\n"
                + "Player: 10S 8H (18)\n"
                + "Result: win\n"
                + "\n"
                + "Money: $1,010.00\n";
        
        assertEquals(expectedOut, testOut.toString());
    }
    
    @Test
    public void testPlayHand2()
    {
        TestShoe.cards = new ArrayList<BlackjackCard>();
        TestShoe.cards.add(new BlackjackCard(6, "H"));
        TestShoe.cards.add(new BlackjackCard(3, "H"));
        TestShoe.cards.add(new BlackjackCard(7, "S"));
        TestShoe.cards.add(new BlackjackCard(3, "C"));
        TestShoe.cards.add(new BlackjackCard(10, "D"));
        TestShoe.cards.add(new BlackjackCard(5, "S"));
        
        String input = "10\ny\ny\nn\n";
        ByteArrayInputStream testIn = new ByteArrayInputStream(input.getBytes());
        System.setIn(testIn);
        
        ByteArrayOutputStream testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
        
        BlackjackUI bjui = new BlackjackUI();
        
        bjui.playHand();
        
        String expectedOut =
                "\nBet: $\n"
                + "Dealer: 10D\n"
                + "Player: 5S 3C (8)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 10D\n"
                + "Player: 5S 3C 3H (11)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 10D\n"
                + "Player: 5S 3C 3H 6H (17)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 10D 7S (17)\n"
                + "Player: 5S 3C 3H 6H (17)\n"
                + "Result: push\n"
                + "\n"
                + "Money: $1,000.00\n";
        
        assertEquals(expectedOut, testOut.toString());
    }
    
    @Test
    public void testPlayHand3()
    {
        TestShoe.cards = new ArrayList<BlackjackCard>();
        TestShoe.cards.add(new BlackjackCard(8, "S"));
        TestShoe.cards.add(new BlackjackCard(7, "C"));
        TestShoe.cards.add(new BlackjackCard(10, "C"));
        TestShoe.cards.add(new BlackjackCard(10, "H"));
        
        String input = "10\nn\n";
        ByteArrayInputStream testIn = new ByteArrayInputStream(input.getBytes());
        System.setIn(testIn);
        
        ByteArrayOutputStream testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
        
        BlackjackUI bjui = new BlackjackUI();
        
        bjui.playHand();
        
        String expectedOut =
                "\nBet: $\n"
                + "Dealer: 10C\n"
                + "Player: 10H 7C (17)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 10C 8S (18)\n"
                + "Player: 10H 7C (17)\n"
                + "Result: loss\n"
                + "\n"
                + "Money: $990.00\n";
        
        assertEquals(expectedOut, testOut.toString());
    }
    
    @Test
    public void testPlayHand4()
    {
        TestShoe.cards = new ArrayList<BlackjackCard>();
        TestShoe.cards.add(new BlackjackCard(5, "C"));
        TestShoe.cards.add(new BlackjackCard(9, "S"));
        TestShoe.cards.add(new BlackjackCard(8, "S"));
        TestShoe.cards.add(new BlackjackCard(10, "C"));
        TestShoe.cards.add(new BlackjackCard(5, "H"));
        
        String input = "10\ny\nn\n";
        ByteArrayInputStream testIn = new ByteArrayInputStream(input.getBytes());
        System.setIn(testIn);
        
        ByteArrayOutputStream testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
        
        BlackjackUI bjui = new BlackjackUI();
        
        bjui.playHand();
        
        String expectedOut =
                "\nBet: $\n"
                + "Dealer: 10C\n"
                + "Player: 5H 8S (13)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 10C\n"
                + "Player: 5H 8S 5C (18)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 10C 9S (19)\n"
                + "Player: 5H 8S 5C (18)\n"
                + "Result: loss\n"
                + "\n"
                + "Money: $990.00\n";
        
        assertEquals(expectedOut, testOut.toString());
    }
    
    @Test
    public void testPlayHand5()
    {
        TestShoe.cards = new ArrayList<BlackjackCard>();
        TestShoe.cards.add(new BlackjackCard(6, "H"));
        TestShoe.cards.add(new BlackjackCard(7, "C"));
        TestShoe.cards.add(new BlackjackCard(5, "H"));
        TestShoe.cards.add(new BlackjackCard(3, "C"));
        TestShoe.cards.add(new BlackjackCard(8, "D"));
        TestShoe.cards.add(new BlackjackCard(10, "H"));
        
        String input = "10\ny\nn\n";
        ByteArrayInputStream testIn = new ByteArrayInputStream(input.getBytes());
        System.setIn(testIn);
        
        ByteArrayOutputStream testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
        
        BlackjackUI bjui = new BlackjackUI();
        
        bjui.playHand();
        
        String expectedOut =
                "\nBet: $\n"
                + "Dealer: 8D\n"
                + "Player: 10H 3C (13)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 8D\n"
                + "Player: 10H 3C 7C (20)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 8D 5H 6H (19)\n"
                + "Player: 10H 3C 7C (20)\n"
                + "Result: win\n"
                + "\n"
                + "Money: $1,010.00\n";
        
        assertEquals(expectedOut, testOut.toString());
    }
    
    @Test
    public void testPlayHand6()
    {
        TestShoe.cards = new ArrayList<BlackjackCard>();
        TestShoe.cards.add(new BlackjackCard(7, "S"));
        TestShoe.cards.add(new BlackjackCard(7, "C"));
        TestShoe.cards.add(new BlackjackCard(6, "D"));
        TestShoe.cards.add(new BlackjackCard(10, "H"));
        TestShoe.cards.add(new BlackjackCard(10, "D"));
        
        String input = "10\ny\n";
        ByteArrayInputStream testIn = new ByteArrayInputStream(input.getBytes());
        System.setIn(testIn);
        
        ByteArrayOutputStream testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
        
        BlackjackUI bjui = new BlackjackUI();
        
        bjui.playHand();
        
        String expectedOut =
                "\nBet: $\n"
                + "Dealer: 10H\n"
                + "Player: 10D 6D (16)\n"
                + "Hit? (y/n): \n"
                + "Dealer: 10H 7C (17)\n"
                + "Player: 10D 6D 7S (23)\n"
                + "Result: loss\n"
                + "\n"
                + "Money: $990.00\n";
        
        assertEquals(expectedOut, testOut.toString());
    }
    
    @Test
    public void testPlayHand7()
    {
        TestShoe.cards = new ArrayList<BlackjackCard>();
        TestShoe.cards.add(new BlackjackCard(10, "S"));
        TestShoe.cards.add(new BlackjackCard(10, "H"));
        TestShoe.cards.add(new BlackjackCard(8, "C"));
        TestShoe.cards.add(new BlackjackCard(BlackjackCard.ACE_VALUE, "S"));
        
        String input = "10\n";
        ByteArrayInputStream testIn = new ByteArrayInputStream(input.getBytes());
        System.setIn(testIn);
        
        ByteArrayOutputStream testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
        
        BlackjackUI bjui = new BlackjackUI();
        
        bjui.playHand();
        
        String expectedOut =
                "\nBet: $\n"
                + "Dealer: 8C 10S (18)\n"
                + "Player: AS 10H (21)\n"
                + "Result: blackjack\n"
                + "\n"
                + "Money: $1,015.00\n";
        
        assertEquals(expectedOut, testOut.toString());
    }
    
    @Test
    public void testPlayHand8()
    {
        TestShoe.cards = new ArrayList<BlackjackCard>();
        TestShoe.cards.add(new BlackjackCard(10, "D"));
        TestShoe.cards.add(new BlackjackCard(10, "H"));
        TestShoe.cards.add(new BlackjackCard(BlackjackCard.ACE_VALUE, "S"));
        TestShoe.cards.add(new BlackjackCard(2, "H"));
        
        String input = "10\n";
        ByteArrayInputStream testIn = new ByteArrayInputStream(input.getBytes());
        System.setIn(testIn);
        
        ByteArrayOutputStream testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
        
        BlackjackUI bjui = new BlackjackUI();
        
        bjui.playHand();
        
        String expectedOut =
                "\nBet: $\n"
                + "Dealer: AS 10D (21)\n"
                + "Player: 2H 10H (12)\n"
                + "Result: loss\n"
                + "\n"
                + "Money: $990.00\n";
        
        assertEquals(expectedOut, testOut.toString());
    }
    
    @Test
    public void testPlayHand9()
    {
        TestShoe.cards = new ArrayList<BlackjackCard>();
        TestShoe.cards.add(new BlackjackCard(BlackjackCard.QUEEN_VALUE, "C"));
        TestShoe.cards.add(new BlackjackCard(BlackjackCard.ACE_VALUE, "S"));
        TestShoe.cards.add(new BlackjackCard(BlackjackCard.ACE_VALUE, "D"));
        TestShoe.cards.add(new BlackjackCard(BlackjackCard.QUEEN_VALUE, "C"));
        
        String input = "10\n";
        ByteArrayInputStream testIn = new ByteArrayInputStream(input.getBytes());
        System.setIn(testIn);
        
        ByteArrayOutputStream testOut = new ByteArrayOutputStream();
        System.setOut(new PrintStream(testOut));
        
        BlackjackUI bjui = new BlackjackUI();
        
        bjui.playHand();
        
        String expectedOut =
                "\nBet: $\n"
                + "Dealer: AD QC (21)\n"
                + "Player: QC AS (21)\n"
                + "Result: push\n"
                + "\n"
                + "Money: $1,000.00\n";
        
        assertEquals(expectedOut, testOut.toString());
    }
}
