require_relative '../euler054.rb'

describe Card, 'succ_value' do
  context 'with an ace' do
    card = Card.new('S', 'A')
    it 'returns two' do
      expect(card.succ_value).to eql :two
    end
  end

  context 'with no ace' do
    card = Card.new('D', '9')
    it 'returns ten' do
      expect(card.succ_value).to eql :ten
    end
  end
end

describe Card, 'succ?' do
  context 'with an ace' do
    card = Card.new('S', 'A')
    context 'with a two' do
      card_two = Card.new('S', '2')
      it 'returns true' do
        expect(card.succ?(card_two)).to eql true
      end
    end

    context 'otherwise' do
      card_two = Card.new('S', '5')
      it 'returns false' do
        expect(card.succ?(card_two)).to eql false
      end
    end
  end

  context 'with a five' do
    card = Card.new('S', '5')
    context 'with a six' do
      card_two = Card.new('S', '6')
      it 'returns true' do
        expect(card.succ?(card_two)).to eql true
      end
    end

    context 'otherwise' do
      card_two = Card.new('S', '8')
      it 'returns false' do
        expect(card.succ?(card_two)).to eql false
      end
    end
  end
end

describe Card, '===' do
  card = Card.new('S', '6')
  context 'is the same card' do
    card_two = Card.new('S', '6')
    it 'returns true' do
      expect(card === card_two).to eql true
    end
  end

  context 'is not the same card' do
    card_two = Card.new('D', '9')
    it 'returns false' do
      expect(card === card_two).to eql false
    end
  end
end

describe Hand, 'initialize' do
  context 'given a string' do
    hand = Hand.new('2C 5C 7D 8S QH')
    it 'generates the proper cards' do
      expect(hand.values).to include(:two, :five, :seven, :eight, :queen)
    end
  end
end

describe Hand, 'flush?' do
  context 'is a flush' do
    hand = Hand.new(Card.new('H', '2'), Card.new('H', '5'), Card.new('H', '9'), Card.new('H', 'J'), Card.new('H', 'K'))
    it 'returns true' do
      expect(hand.flush?).to eql true
    end
  end

  context 'is not a flush' do
    hand = Hand.new(Card.new('S', '2'), Card.new('H', '5'), Card.new('H', '9'), Card.new('H', 'J'), Card.new('H', 'K'))
    it 'returns false' do
      expect(hand.flush?).to eql false
    end
  end
end

describe Hand, 'straight?' do
  context 'is a straight' do
    context 'there is an ace' do
      hand = Hand.new(Card.new('D', 'A'), Card.new('S', '2'), Card.new('S', '3'), Card.new('S', '4'), Card.new('S', '5'))
      it 'returns true' do
        expect(hand.straight?).to eql true
      end
    end

    context 'there is no ace' do
      hand = Hand.new(Card.new('S', '3'), Card.new('S', '4'), Card.new('D', '5'), Card.new('C', '6'), Card.new('D', '7'))
      it 'returns true' do
        expect(hand.straight?).to eql true
      end
    end
  end

  context 'is not a straight' do
    hand = Hand.new(Card.new('D', 'A'), Card.new('C', '6'), Card.new('S', '8'), Card.new('C', '10'), Card.new('S', 'J'))
    it 'returns false' do
      expect(hand.straight?).to eql false
    end
  end
end

describe Hand, 'straight_flush?' do
  context 'is a straight flush' do
    hand = Hand.new(Card.new('S', '8'), Card.new('S', '9'), Card.new('S', '10'), Card.new('S', 'J'), Card.new('S', 'Q'))
    it 'returns true' do
      expect(hand.straight_flush?).to eql true
    end
  end

  context 'is not a straight flush' do
    hand = Hand.new(Card.new('D', 'A'), Card.new('C', '6'), Card.new('S', '8'), Card.new('C', '10'), Card.new('S', 'J'))
    it 'returns false' do
      expect(hand.straight_flush?).to eql false
    end
  end
end

describe Hand, 'royal_flush?' do
  context 'is a royal flush' do
    hand = Hand.new(Card.new('S', '10'), Card.new('S', 'J'), Card.new('S', 'Q'), Card.new('S', 'K'), Card.new('S', 'A'))
    it 'returns true' do
      expect(hand.royal_flush?).to eql true
    end
  end

  context 'is not a royal flush' do
    hand = Hand.new(Card.new('D', 'A'), Card.new('C', '6'), Card.new('S', '8'), Card.new('C', '10'), Card.new('S', 'J'))
    it 'returns false' do
      expect(hand.royal_flush?).to eql false
    end
  end
end

describe Hand, 'four_of_a_kind' do
  context 'contains a four of a kind' do
    hand = Hand.new(Card.new('S', '9'), Card.new('D', '9'), Card.new('C', '9'), Card.new('H', '9'), Card.new('S', '2'))
    it 'returns true' do
      expect(hand.four_of_a_kind?).to eql true
    end
  end

  context 'does not contain a four of a kind' do
    hand = Hand.new(Card.new('D', 'A'), Card.new('C', '6'), Card.new('S', '8'), Card.new('C', '10'), Card.new('S', 'J'))
    it 'returns false' do
      expect(hand.four_of_a_kind?).to eql false
    end
  end
end

describe Hand, 'three_of_a_kind' do
  context 'contains a three of a kind' do
    hand = Hand.new(Card.new('S', '9'), Card.new('D', '9'), Card.new('C', '9'), Card.new('D', 'J'), Card.new('S', '2'))
    it 'returns true' do
      expect(hand.three_of_a_kind?).to eql true
    end
  end

  context 'does not contain a three of a kind' do
    hand = Hand.new(Card.new('D', 'A'), Card.new('C', '6'), Card.new('S', '8'), Card.new('C', '10'), Card.new('S', 'J'))
    it 'returns false' do
      expect(hand.three_of_a_kind?).to eql false
    end
  end
end

describe Hand, 'full_house?' do
  context 'is a full house' do
    hand = Hand.new(Card.new('S', '9'), Card.new('D', '9'), Card.new('C', '9'), Card.new('D', '2'), Card.new('S', '2'))
    it 'returns true' do
      expect(hand.full_house?).to eql true
    end
  end

  context 'is not a full house' do
    hand = Hand.new(Card.new('D', 'A'), Card.new('C', '6'), Card.new('S', '8'), Card.new('C', '10'), Card.new('S', 'J'))
    it 'returns false' do
      expect(hand.full_house?).to eql false
    end
  end
end

describe Hand, 'two_pair?' do
  context 'contains a two pair' do
    hand = Hand.new(Card.new('S', '3'), Card.new('D', '3'), Card.new('C', '7'), Card.new('H', '7'), Card.new('S', 'K'))
    it 'returns true' do
      expect(hand.two_pair?).to eql true
    end
  end

  context 'does not contain a two pair' do
    hand = Hand.new(Card.new('D', 'A'), Card.new('C', '6'), Card.new('S', '8'), Card.new('C', '10'), Card.new('S', 'J'))
    it 'returns false' do
      expect(hand.two_pair?).to eql false
    end
  end
end

describe Hand, 'pair?' do
  context 'contains a pair' do
    hand = Hand.new(Card.new('S', '3'), Card.new('D', '3'), Card.new('C', '8'), Card.new('H', '7'), Card.new('S', 'K'))
    it 'returns true' do
      expect(hand.pair?).to eql true
    end
  end

  context 'does not contain a pair' do
    hand = Hand.new(Card.new('D', 'A'), Card.new('C', '6'), Card.new('S', '8'), Card.new('C', '10'), Card.new('S', 'J'))
    it 'returns false' do
      expect(hand.pair?).to eql false
    end
  end
end

describe Hand, 'aces_low' do
  context 'hand contains an ace' do
    ace = Card.new('S', 'A')
    hand = Hand.new(ace, Card.new('D', '4'), Card.new('S', '9'), Card.new('C', '10'), Card.new('C', 'K'))
    it 'returns a list with the ace first' do
      expect(hand.aces_low.first).to eql ace
    end
  end

  context 'hand contains two aces' do
    first_ace = Card.new('S', 'A')
    second_ace = Card.new('D', 'A')
    hand = Hand.new(first_ace, second_ace, Card.new('S', '9'), Card.new('C', '10'), Card.new('C', 'K'))
    it 'returns a list with an ace first' do
      expect(hand.aces_low.first.value).to eql :ace
    end

    it 'returns a list with an ace second' do
      expect(hand.aces_low[1].value).to eql :ace
    end
  end
end

describe Hand, 'ace?' do
  context 'hand contains an ace' do
    hand = Hand.new(Card.new('S', 'A'), Card.new('D', '4'), Card.new('S', '9'), Card.new('C', '10'), Card.new('C', 'K'))
    it 'returns true' do
      expect(hand.ace?).to eql true
    end
  end

  context 'hand does not contain an ace' do
    hand = Hand.new(Card.new('C', '5'), Card.new('D', '4'), Card.new('S', '9'), Card.new('C', '10'), Card.new('C', 'K'))
    it 'returns false' do
      expect(hand.ace?).to eql false
    end
  end
end

describe Hand, 'high_card' do
  context 'highest card is a king' do
    hand_high_card = Card.new('C', 'K')
    hand = Hand.new(Card.new('S', '5'), Card.new('D', '4'), Card.new('S', '9'), Card.new('C', '10'), hand_high_card)
    it 'returns the king' do
      expect(hand.high_card).to eql hand_high_card
    end
  end
end

describe Hand, 'high_match_value' do
  context 'highest pair in two pair is kings' do
    hand = Hand.new(Card.new('S', 'K'), Card.new('D', '4'), Card.new('S', '4'), Card.new('C', '10'), Card.new('C', 'K'))
    it 'returns king value' do
      expect(hand.high_match_value).to eql :king
    end
  end
end

describe Hand, 'full_house_high_value' do
  context 'three pair in a full house is kings' do
    hand = Hand.new(Card.new('S', 'K'), Card.new('D', '4'), Card.new('S', '4'), Card.new('H', 'K'), Card.new('C', 'K'))
    it 'returns king value' do
      expect(hand.full_house_high_value).to eql :king
    end
  end
end

describe Hand, 'full_house_low_value' do
  context 'full house with three kings and two jacks' do
    hand = Hand.new(Card.new('S', 'K'), Card.new('D', 'K'), Card.new('C', 'J'), Card.new('H', 'J'), Card.new('H', 'K'))
    it 'returns jack value' do
      expect(hand.low_match_value).to eql :jack
    end
  end
end

describe Hand, 'low_match_value' do
  context 'two pair with kings and jacks' do
    hand = Hand.new(Card.new('S', 'K'), Card.new('D', 'K'), Card.new('C', 'J'), Card.new('H', 'J'), Card.new('D', '2'))
    it 'returns jack value' do
      expect(hand.low_match_value).to eql :jack
    end
  end
end

describe Hand, 'kicker' do
  context 'four of a kind with king kicker' do
    king_card = Card.new('S', 'K')
    hand = Hand.new(Card.new('S', '9'), Card.new('D', '9'), Card.new('C', '9'), Card.new('H', '9'), king_card)
    it 'returns the king kicker' do
      expect(hand.kicker).to eql king_card
    end
  end

  context 'three of a kind with king kicker' do
    king_card = Card.new('S', 'K')
    hand = Hand.new(Card.new('S', '9'), Card.new('D', '9'), Card.new('C', '9'), Card.new('H', '7'), king_card)
    it 'returns the king kicker' do
      expect(hand.kicker).to eql king_card
    end
  end

  context 'two pair with king kicker' do

  end
end

describe Hand, '<=>' do
  context 'pair of fives vs pair of eights' do
    hand_one = Hand.new(Card.new('H', '5'), Card.new('C', '5'), Card.new('S', '6'), Card.new('S', '7'), Card.new('D', 'K'))
    hand_two = Hand.new(Card.new('C', '2'), Card.new('S', '3'), Card.new('S', '8'), Card.new('D', '8'), Card.new('D', '10'))
    it 'pair of eights is higher' do
      expect(hand_two).to be > hand_one
    end
  end

  context 'ace high vs queen high' do
    hand_one = Hand.new('5D 8C 9S JS AC')
    hand_two = Hand.new('2C 5C 7D 8S QH')
    it 'ace high is higher' do
      expect(hand_one).to be > hand_two
    end
  end

  context 'three aces vs diamond flush' do
    hand_one = Hand.new('2D 9C AS AH AC')
    hand_two = Hand.new('3D 6D 7D TD QD')
    it 'flush is higher' do
      expect(hand_two).to be > hand_one
    end
  end

  context 'pair of queens nine high vs pair of queens seven high' do
    hand_one = Hand.new('4D 6S 9H QH QC')
    hand_two = Hand.new('3D 6D 7H QD QS')
    it 'nine high is higher' do
      expect(hand_one).to be > hand_two
    end
  end

  context 'full house with three fours vs full house with three threes' do
    hand_one = Hand.new('2H 2D 4C 4D 4S')
    hand_two = Hand.new('3C 3D 3S 9S 9D')
    it 'seven high is higher' do
      expect(hand_one).to be > hand_two
    end
  end
end