mod common;

#[cfg(test)]
mod snippets {
    use dittolive_ditto::error::DittoError;

    use super::common::*;

    #[test]
    fn network_remote_ditto() -> Result<(), DittoError> {
        let (_root, ditto) = get_test_ditto(None).unwrap();
        network_remote_ditto_impl(ditto)?;

        Ok(())
    }

    fn network_remote_ditto_impl(ditto: dittolive_ditto::prelude::Ditto) -> Result<(), DittoError> {
        //@ditto/snippet-start network-remote-ditto
        let mut config = TransportConfig::new(); // empty

        config
            .connect
            .tcp_servers
            .insert("135.1.5.5:12345".to_string()); // Custom TCP Listener
        config
            .connect
            .tcp_servers
            .insert("185.1.5.5:12345".to_string()); // Custom TCP Listener
        config
            .connect
            .websocket_urls
            .insert("wss://example.com".to_string()); // Custom WS endpoint

        ditto.set_transport_config(config);
        ditto.sync().start()?;
        //@ditto/snippet-end
        ditto.sync().stop();
        Ok(())
    }

    #[test]
    fn network_listen() -> Result<(), DittoError> {
        let (_root, ditto) = get_test_ditto(None).unwrap();
        network_listen_impl(ditto)?;

        Ok(())
    }

    fn network_listen_impl(ditto: dittolive_ditto::prelude::Ditto) -> Result<(), DittoError> {
        //@ditto/snippet-start network-listen
        let mut config = TransportConfig::new(); // empty

        config.listen.tcp.enabled = true;
        config.listen.tcp.interface_ip = "0.0.0.0".to_string();
        config.listen.tcp.port = 4000;
        config.listen.http.enabled = false;

        ditto.set_transport_config(config);
        ditto.sync().start()?;
        //@ditto/snippet-end
        ditto.sync().stop();
        Ok(())
    }

    #[test]
    fn sync_groups() -> Result<(), DittoError> {
        let (_root, ditto) = get_test_ditto(None).unwrap();
        sync_groups_impl(ditto)?;

        Ok(())
    }

    fn sync_groups_impl(ditto: dittolive_ditto::prelude::Ditto) -> Result<(), DittoError> {
        //@ditto/snippet-start transport-sync-groups
        let mut config = TransportConfig::new(); // empty

        config.enable_all_peer_to_peer();
        config.global.sync_group = 1234;

        ditto.set_transport_config(config);
        ditto.sync().start()?;
        //@ditto/snippet-end
        ditto.sync().stop();
        Ok(())
    }

    #[test]
    fn network_three() -> Result<(), DittoError> {
        let (_root, ditto) = get_test_ditto(None).unwrap();
        network_three_impl(ditto)?;

        Ok(())
    }

    fn network_three_impl(ditto: dittolive_ditto::prelude::Ditto) -> Result<(), DittoError> {
        //@ditto/snippet-start network-multiple-transports
        let mut config = TransportConfig::new(); // empty

        // 1. Enable auto-discovery of peer to peer connections
        config.enable_all_peer_to_peer(); // Auto-connect via lan and bluetooth

        // 2. Configure TCP Listener
        config.listen.tcp.enabled = true;
        config.listen.tcp.interface_ip = "0.0.0.0".to_string();
        config.listen.tcp.port = 4000;
        config.listen.http.enabled = false;

        // 3. Configure explicit, hard coded connections
        config
            .connect
            .tcp_servers
            .insert("135.1.5.5:12345".to_string()); // Custom TCP Listener
        config
            .connect
            .websocket_urls
            .insert("wss://example.com".to_string()); // Custom WS endpoint

        ditto.set_transport_config(config);
        ditto.sync().start()?;
        //@ditto/snippet-end
        ditto.sync().stop();
        Ok(())
    }

    #[tokio::test]
    async fn dittolive_homepage() -> anyhow::Result<()> {
        let (_root, ditto) = get_test_ditto(None)?;
        dittolive_homepage_impl(ditto).await?;

        Ok(())
    }

    async fn dittolive_homepage_impl(ditto: dittolive_ditto::prelude::Ditto) -> anyhow::Result<()> {
        use dittolive_ditto::dql::QueryResult;

        //@ditto/snippet-start dittolive-homepage
        //@ditto/snippet-include-next-line
        // let ditto = Ditto::new(...);
        ditto.sync().start()?;

        let results = ditto
            .store()
            .execute("INSERT INTO cars DOCUMENTS ({ 'color': 'blue' })")
            .await?;

        let observer = ditto.store().register_observer(
            "SELECT * FROM cars",
            move |_result: QueryResult| {
                // handle changes
            },
        )?;

        let subscription = ditto.sync().register_subscription("SELECT * FROM cars")?;

        //@ditto/snippet-end
        drop(subscription);
        drop(observer);
        drop(results);

        Ok(())
    }
}
