use crate::message::*;
use crate::system::Component;
use std::sync::mpsc::{channel, Sender, Receiver};
use std::fs::File;
use std::io::prelude::*;

pub struct MessageSniffer {
    log_file: String,
    input_channel_sender: Sender<Message>,
    input_channel_receiver: Receiver<Message>
}

impl MessageSniffer {
    pub fn new(log_file: &str)-> Self {
        let (sender, receiver) = channel::<Message>();

        Self {
            log_file: log_file.to_string(),
            input_channel_sender: sender,
            input_channel_receiver: receiver
        }
    }
}

impl Component for MessageSniffer {
    fn get_name(&self) -> &str {
        "MessageSniffer"
    }

    fn get_sender(&self) -> Sender<Message> {
        self.input_channel_sender.clone()
    }

    fn listen_to(&self) -> Vec<MessageType> {
        vec![
            MessageType::CardInserted,
            MessageType::Debug,
            MessageType::Error,
            MessageType::Halt,
            MessageType::KeyPressed,
            MessageType::SystemStatusChanged,
            MessageType::Print,
            MessageType::PrintProgramSwitch,
            MessageType::ProgramStarted,
            MessageType::ProgramEnded,
            MessageType::ProgramStopped,
            MessageType::RecordProgramSwitch,
            MessageType::SetPrecision,
            MessageType::StoreTextOnCard,
            MessageType::TextRead
        ]
    }

    fn run(&mut self) {
        loop {
            let message = self.input_channel_receiver.recv().unwrap();

	    let mut f = File::options()
                .write(true)
                .create(true)
                .append(true)
                .open(&self.log_file)
                .unwrap();

                writeln!(&mut f, "{:?}", message).unwrap();
        
            if message == Message::Halt {
                break;
            }
        }
    }
}
