use std::sync::Arc;

use serde_json::Value;

use crate::pipe::{Action, CommandOutput, ExecutionSurfaceMetadata, PipeError};

pub trait BrowserBackend: Send + Sync {
    fn invoke(
        &self,
        action: Action,
        params: Value,
        expected_domain: &str,
    ) -> Result<CommandOutput, PipeError>;

    fn surface_metadata(&self) -> ExecutionSurfaceMetadata;

    fn supports_eval(&self) -> bool {
        true
    }

    fn supports_live_input(&self) -> bool {
        false
    }
}

impl<T: BrowserBackend + ?Sized> BrowserBackend for Arc<T> {
    fn invoke(
        &self,
        action: Action,
        params: Value,
        expected_domain: &str,
    ) -> Result<CommandOutput, PipeError> {
        self.as_ref().invoke(action, params, expected_domain)
    }

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

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

    fn supports_live_input(&self) -> bool {
        self.as_ref().supports_live_input()
    }
}
