use std::sync::Arc;

use serde::Serialize;
use tokio::sync::RwLock;

use crate::{
    interpret::{Interpret, InterpretStatus},
    score::Score,
    topology::Topology,
};

use super::{OPNsenseShellCommandScore, OPNsenseShellInterpret};

#[derive(Debug, Clone)]
pub struct OPNSenseLaunchUpgrade {
    pub opnsense: Arc<RwLock<opnsense_config::Config>>,
}

impl Serialize for OPNSenseLaunchUpgrade {
    fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
    where
        S: serde::Serializer,
    {
        todo!("See comment in OPNSenseShellCommandScore and apply the same idea here")
    }
}

impl<T: Topology> Score<T> for OPNSenseLaunchUpgrade {
    fn create_interpret(&self) -> Box<dyn Interpret<T>> {
        let score = OPNsenseShellCommandScore {
            opnsense: self.opnsense.clone(),
            command: "/usr/local/opnsense/scripts/firmware/update.sh".to_string(),
        };

        Box::new(OPNsenseShellInterpret {
            status: InterpretStatus::QUEUED,
            score,
        })
    }

    fn name(&self) -> String {
        "OPNSenseLaunchUpgrade".to_string()
    }
}
