use std::sync::Arc;

use serde_json::Value;

use crate::browser::BrowserBackend;
use crate::pipe::{Action, BrowserPipeTool, CommandOutput, ExecutionSurfaceMetadata, PipeError, Transport};
use crate::security::MacPolicy;

pub struct PipeBrowserBackend<T: Transport> {
    inner: BrowserPipeTool<T>,
}

impl<T: Transport> PipeBrowserBackend<T> {
    pub fn new(transport: Arc<T>, mac_policy: MacPolicy, session_key: Vec<u8>) -> Self {
        Self {
            inner: BrowserPipeTool::new(transport, mac_policy, session_key),
        }
    }

    pub fn from_inner(inner: BrowserPipeTool<T>) -> Self {
        Self { inner }
    }

    pub fn with_response_timeout(mut self, response_timeout: std::time::Duration) -> Self {
        self.inner = self.inner.with_response_timeout(response_timeout);
        self
    }
}

impl<T: Transport> Clone for PipeBrowserBackend<T> {
    fn clone(&self) -> Self {
        Self {
            inner: self.inner.clone(),
        }
    }
}

impl<T: Transport> BrowserBackend for PipeBrowserBackend<T> {
    fn invoke(
        &self,
        action: Action,
        params: Value,
        expected_domain: &str,
    ) -> Result<CommandOutput, PipeError> {
        self.inner.invoke(action, params, expected_domain)
    }

    fn surface_metadata(&self) -> ExecutionSurfaceMetadata {
        self.inner.surface_metadata()
    }

    fn supports_eval(&self) -> bool {
        self.inner.supports_eval()
    }
}
