1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
// Copyright (c) 2024-2099 xmpp-rs contributors.
//
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

use std::collections::HashMap;
use std::io;

use futures::stream::StreamExt;
use tokio::{
    sync::mpsc::{UnboundedReceiver, UnboundedSender},
    sync::oneshot,
};
use tokio_xmpp::parsers::{
    iq::IqType, message::Message, minidom::Element, presence::Presence, stanza_error::StanzaError,
};
use tokio_xmpp::{connect::ServerConnector, AsyncClient as TokioXmppClient};

use crate::jid::Jid;

#[derive(Debug)]
pub enum IqRequestType {
    Get(Element),
    Set(Element),
}

#[derive(Debug)]
pub struct IqRequest {
    pub to: Jid,
    pub data: IqRequestType,
}

#[derive(Debug)]
pub enum IqResponseType {
    Result(Option<Element>),
    Error(StanzaError),
}

#[derive(Debug)]
pub struct IqResponse {
    pub from: Option<Jid>,
    pub to: Option<Jid>,
    pub data: IqResponseType,
}

impl From<IqRequestType> for IqType {
    fn from(other: IqRequestType) -> IqType {
        match other {
            IqRequestType::Get(e) => IqType::Get(e),
            IqRequestType::Set(e) => IqType::Set(e),
        }
    }
}

impl From<IqResponseType> for IqType {
    fn from(other: IqResponseType) -> IqType {
        match other {
            IqResponseType::Result(e) => IqType::Result(e),
            IqResponseType::Error(e) => IqType::Error(e),
        }
    }
}

#[derive(Debug)]
pub enum Request {
    SendMessage {
        message: Message,
        response: oneshot::Sender<io::Result<()>>,
    },
    SendPresence {
        presence: Presence,
        response: oneshot::Sender<io::Result<()>>,
    },
    SendIq {
        to: Jid,
        data: IqRequestType,
        response: oneshot::Sender<io::Result<IqResponse>>,
    },
    Disconnect {
        response: oneshot::Sender<io::Result<()>>,
    },
}

#[derive(Debug)]
pub enum NonTransactional {
    Presence(Presence),
    Message(Message),
}

pub(crate) async fn xml_stream_worker<C: ServerConnector>(
    mut client: TokioXmppClient<C>,
    mut _local_rx: UnboundedReceiver<Request>,
    mut _misc_tx: UnboundedSender<NonTransactional>,
) {
    println!("BAR0");
    let _pending_iqs: HashMap<(String, Option<String>), oneshot::Sender<io::Result<()>>> =
        HashMap::new();
    println!("BAR1");

    /*
    loop {
        println!("BAR1");
        tokio::select! {
            req = _local_rx.recv() => match req {
                Some(_) => (),
                None => {
                    // Lost client.
                }
            },
            msg = client.next() => match msg {
                Some(_) => println!("FOO0"),
                None => break,
            }
        }
    }
    */

    println!("BAR2, {:?}", client);
    println!("BAR3: {:?}", client.next().await);
    loop {
        while let Some(event) = client.next().await {
            println!("BAR4, {:?}", event);
        }
    }
}