use crate::opamp::Client;

pub struct Disconnected;
pub struct Connecting;
pub struct Connected;
pub struct Polling;
pub struct Executing;

pub trait State {
    fn evaluate(self: Box<Self>, client: &mut dyn Client) -> Box<dyn State>;
}

impl State for Disconnected {
    fn evaluate(self: Box<Self>, client: &mut dyn Client) -> Box<dyn State> {
        if client.process(&self) {
            Box::new(Connecting)
        } else {
            self
        }
    }
}

impl State for Connecting {
    fn evaluate(self: Box<Self>, client: &mut dyn Client) -> Box<dyn State> {
        if client.process(&self) {
            Box::new(Connected)
        } else {
            self
        }
    }
}

impl State for Connected {
    fn evaluate(self: Box<Self>, client: &mut dyn Client) -> Box<dyn State> {
        if client.process(&self) {
            Box::new(Polling)
        } else {
            self
        }
    }
}

impl State for Polling {
    fn evaluate(self: Box<Self>, client: &mut dyn Client) -> Box<dyn State> {
        if client.process(&self) {
            Box::new(Executing)
        } else {
            self
        }
    }
}

impl State for Executing {
    fn evaluate(self: Box<Self>, client: &mut dyn Client) -> Box<dyn State> {
        if client.process(&self) {
            Box::new(Polling)
        } else {
            self
        }
    }
}
