mod board;

use board::tictactoe::Board as TicTacToe;
use board::Game;
use std::io;
use std::io::prelude::*;

fn prompt<Player>(turn: Player)
where
    Player: std::fmt::Display,
{
    print!("{}>", turn);
    io::stdout().flush().unwrap();
}

fn play<G, Move, Player>(mut board: G)
where
    G: Game<Move, Player> + std::fmt::Display,
    Player: Copy + std::fmt::Display + Default + std::ops::Not<Output = Player>,
    Move: std::str::FromStr,
{
    let mut stdin = std::io::stdin().lock();
    let mut player = Player::default();

    println!("Let start");
    println!("{board}");
    prompt(player);

    loop {
        let mut input = String::default();
        stdin.read_line(&mut input).unwrap();
        let str_move = input.trim_end();
        if let Ok(m) = str_move.parse() {
            board.do_move(player, &m);
            println!("{board}");
            if board.has_won(player) {
                println!("Victory!");
                return;
            }
            player = !player;
        }
        prompt(player);
    }
}

fn main() {
    let board = TicTacToe::new();
    //let board = board::coin_flip::FlipCoin::new(42);
    play(board);
}

// Will only be build in 'test' configuration
#[cfg(test)]
// A module where the tests are located, more on modules later
mod tests {
    #[test]
    fn should_pass() {
        assert!(true);
    }
    #[test]
    #[should_panic]
    fn should_panic() {
        panic!("Doing wrong things on purpose here!");
    }
}