1use anyhow::{anyhow, Result};
2use collections::HashMap;
3use futures::{channel::mpsc, future};
4use gpui::executor::Background;
5use lazy_static::lazy_static;
6use media::core_video::CVImageBuffer;
7use parking_lot::Mutex;
8use std::{future::Future, sync::Arc};
9
10lazy_static! {
11 static ref SERVERS: Mutex<HashMap<String, Arc<FakeServer>>> = Default::default();
12}
13
14pub struct FakeServer {
15 url: String,
16 secret_key: String,
17 rooms: Mutex<HashMap<String, FakeServerRoom>>,
18 background: Arc<Background>,
19}
20
21impl FakeServer {
22 pub fn create(
23 url: String,
24 secret_key: String,
25 background: Arc<Background>,
26 ) -> Result<Arc<FakeServer>> {
27 let mut servers = SERVERS.lock();
28 if servers.contains_key(&url) {
29 Err(anyhow!("a server with url {:?} already exists", url))
30 } else {
31 let server = Arc::new(FakeServer {
32 url: url.clone(),
33 secret_key,
34 rooms: Default::default(),
35 background,
36 });
37 servers.insert(url, server.clone());
38 Ok(server)
39 }
40 }
41
42 fn get(url: &str) -> Result<Arc<FakeServer>> {
43 Ok(SERVERS
44 .lock()
45 .get(url)
46 .ok_or_else(|| anyhow!("no server found for url"))?
47 .clone())
48 }
49
50 pub fn teardown(&self) -> Result<()> {
51 SERVERS
52 .lock()
53 .remove(&self.url)
54 .ok_or_else(|| anyhow!("server with url {:?} does not exist", self.url))?;
55 Ok(())
56 }
57
58 async fn join_room(&self, token: String, client_room: Arc<Room>) -> Result<()> {
59 self.background.simulate_random_delay().await;
60 let claims = live_kit_server::token::validate(&token, &self.secret_key)?;
61 let identity = claims.sub.unwrap().to_string();
62 let room = claims.video.room.unwrap();
63 let mut server_rooms = self.rooms.lock();
64 let room = server_rooms
65 .get_mut(&*room)
66 .ok_or_else(|| anyhow!("room {} does not exist", room))?;
67 room.clients.insert(identity, client_room);
68 Ok(())
69 }
70}
71
72struct FakeServerRoom {
73 clients: HashMap<Sid, Arc<Room>>,
74}
75
76impl FakeServerRoom {}
77
78pub type Sid = String;
79
80pub struct Room;
81
82impl Room {
83 pub fn new() -> Arc<Self> {
84 Arc::new(Self)
85 }
86
87 pub fn connect(self: &Arc<Self>, url: &str, token: &str) -> impl Future<Output = Result<()>> {
88 let this = self.clone();
89 let url = url.to_string();
90 let token = token.to_string();
91 async move {
92 let server = FakeServer::get(&url)?;
93 server.join_room(token, this).await?;
94 Ok(())
95 }
96 }
97
98 pub fn publish_video_track(
99 &self,
100 track: &LocalVideoTrack,
101 ) -> impl Future<Output = Result<LocalTrackPublication>> {
102 future::pending()
103 }
104
105 pub fn unpublish_track(&self, publication: LocalTrackPublication) {}
106
107 pub fn remote_video_tracks(&self, participant_id: &str) -> Vec<Arc<RemoteVideoTrack>> {
108 Default::default()
109 }
110
111 pub fn remote_video_track_updates(&self) -> mpsc::UnboundedReceiver<RemoteVideoTrackUpdate> {
112 mpsc::unbounded().1
113 }
114}
115
116impl Drop for Room {
117 fn drop(&mut self) {
118 todo!()
119 }
120}
121
122pub struct LocalTrackPublication;
123
124pub struct LocalVideoTrack;
125
126impl LocalVideoTrack {
127 pub fn screen_share_for_display(display: &MacOSDisplay) -> Self {
128 Self
129 }
130}
131
132pub struct RemoteVideoTrack {
133 sid: Sid,
134 publisher_id: Sid,
135}
136
137impl RemoteVideoTrack {
138 pub fn sid(&self) -> &str {
139 &self.sid
140 }
141
142 pub fn publisher_id(&self) -> &str {
143 &self.publisher_id
144 }
145
146 pub fn add_renderer<F>(&self, callback: F)
147 where
148 F: 'static + FnMut(CVImageBuffer),
149 {
150 }
151}
152
153pub enum RemoteVideoTrackUpdate {
154 Subscribed(Arc<RemoteVideoTrack>),
155 Unsubscribed { publisher_id: Sid, track_id: Sid },
156}
157
158pub struct MacOSDisplay;
159
160pub fn display_sources() -> impl Future<Output = Result<Vec<MacOSDisplay>>> {
161 future::pending()
162}