use mpstthree::binary::struct_trait::{end::End, recv::Recv, send::Send, session::Session};
use mpstthree::meshedchannels::MeshedChannels;
use mpstthree::role::Role;
use mpstthree::checker_concat;
use mpstthree::role::a::RoleA;
use mpstthree::role::all_to_b::RoleAlltoB;
use mpstthree::role::b::RoleB;
use mpstthree::role::b_to_all::RoleBtoAll;
use mpstthree::role::c::RoleC;
use mpstthree::role::end::RoleEnd;
use mpstthree::name::a::NameA;
use mpstthree::name::b::NameB;
use mpstthree::name::c::NameC;
use mpstthree::functionmpst::ChooseMpst;
use mpstthree::functionmpst::OfferMpst;
use petgraph::dot::Dot;
type CtoBClose = End;
type CtoAClose = End;
type CtoBVideo<N> = Recv<N, Send<N, End>>;
type CtoAVideo<N> = Send<N, Recv<N, End>>;
type AtoCClose = <CtoAClose as Session>::Dual;
type AtoBClose = End;
type AtoCVideo<N> = <CtoAVideo<N> as Session>::Dual;
type BtoAClose = <AtoBClose as Session>::Dual;
type BtoCClose = <CtoBClose as Session>::Dual;
type BtoCVideo<N> = <CtoBVideo<N> as Session>::Dual;
type StackCEnd = RoleEnd;
type StackCVideo = RoleB<RoleA<RoleA<RoleB<RoleEnd>>>>;
type StackCVideoDual = <StackCVideo as Role>::Dual;
type StackCFull = RoleB<RoleB<RoleAlltoB<RoleEnd, RoleEnd>>>;
type StackAEnd = RoleEnd;
type StackAVideo = RoleC<RoleC<RoleEnd>>;
type StackAVideoDual = <StackAVideo as Role>::Dual;
type StackAFull = RoleAlltoB<RoleEnd, RoleEnd>;
type StackBEnd = RoleEnd;
type StackBVideo = RoleC<RoleC<RoleEnd>>;
type StackBChoice = RoleBtoAll<StackBVideo, StackBEnd>;
type StackBFull = RoleC<RoleC<StackBChoice>>;
type ChooseBtoC<N> =
ChooseMpst<AtoCVideo<N>, BtoCVideo<N>, AtoCClose, BtoCClose, StackCVideoDual, StackCEnd, NameC>;
type ChooseBtoA<N> =
ChooseMpst<BtoAClose, CtoAVideo<N>, BtoAClose, CtoAClose, StackAVideoDual, StackAEnd, NameA>;
type InitB<N> = Send<N, Recv<N, ChooseBtoC<N>>>;
type EndpointBFull<N> = MeshedChannels<ChooseBtoA<N>, InitB<N>, StackBFull, NameB>;
type OfferC<N> =
OfferMpst<CtoAVideo<N>, CtoBVideo<N>, CtoAClose, CtoBClose, StackCVideo, StackCEnd, NameC>;
type InitC<N> = Recv<N, Send<N, OfferC<N>>>;
type EndpointCFull<N> = MeshedChannels<End, InitC<N>, StackCFull, NameC>;
type OfferA<N> =
OfferMpst<AtoBClose, AtoCVideo<N>, AtoBClose, AtoCClose, StackAVideo, StackAEnd, NameA>;
type EndpointAFull<N> = MeshedChannels<OfferA<N>, End, StackAFull, NameA>;
pub fn main() {
let (graphs, kmc) = checker_concat!(
"checking_choice",
EndpointAFull<i32>,
EndpointCFull<i32>,
EndpointBFull<i32>
)
.unwrap();
let graph_a = &graphs["RoleA"];
assert_eq!(
format!("{:?}", Dot::new(&graph_a)),
"digraph {\n \
0 [ label = \"\\\"0\\\"\" ]\n \
1 [ label = \"\\\"0.1\\\"\" ]\n \
2 [ label = \"\\\"0.2\\\"\" ]\n \
3 [ label = \"\\\"0.3\\\"\" ]\n \
4 [ label = \"\\\"0.1\\\"\" ]\n \
0 -> 1 [ label = \"\\\"RoleA?RoleC: i32\\\"\" ]\n \
1 -> 2 [ label = \"\\\"RoleA!RoleC: i32\\\"\" ]\n \
2 -> 3 [ label = \"\\\"0\\\"\" ]\n \
0 -> 4 [ label = \"\\\"0\\\"\" ]\n\
}\n"
);
let graph_b = &graphs["RoleB"];
assert_eq!(
format!("{:?}", Dot::new(&graph_b)),
"digraph {\n \
0 [ label = \"\\\"0\\\"\" ]\n \
1 [ label = \"\\\"1\\\"\" ]\n \
2 [ label = \"\\\"2\\\"\" ]\n \
3 [ label = \"\\\"2.1\\\"\" ]\n \
4 [ label = \"\\\"2.2\\\"\" ]\n \
5 [ label = \"\\\"2.3\\\"\" ]\n \
6 [ label = \"\\\"2.1\\\"\" ]\n \
0 -> 1 [ label = \"\\\"RoleB!RoleC: i32\\\"\" ]\n \
1 -> 2 [ label = \"\\\"RoleB?RoleC: i32\\\"\" ]\n \
2 -> 3 [ label = \"\\\"RoleB!RoleC: i32\\\"\" ]\n \
3 -> 4 [ label = \"\\\"RoleB?RoleC: i32\\\"\" ]\n \
4 -> 5 [ label = \"\\\"0\\\"\" ]\n \
2 -> 6 [ label = \"\\\"0\\\"\" ]\n\
}\n"
);
let graph_c = &graphs["RoleC"];
assert_eq!(
format!("{:?}", Dot::new(&graph_c)),
"digraph {\n \
0 [ label = \"\\\"0\\\"\" ]\n \
1 [ label = \"\\\"1\\\"\" ]\n \
2 [ label = \"\\\"2\\\"\" ]\n \
3 [ label = \"\\\"2.1\\\"\" ]\n \
4 [ label = \"\\\"2.2\\\"\" ]\n \
5 [ label = \"\\\"2.3\\\"\" ]\n \
6 [ label = \"\\\"2.4\\\"\" ]\n \
7 [ label = \"\\\"2.5\\\"\" ]\n \
8 [ label = \"\\\"2.1\\\"\" ]\n \
0 -> 1 [ label = \"\\\"RoleC?RoleB: i32\\\"\" ]\n \
1 -> 2 [ label = \"\\\"RoleC!RoleB: i32\\\"\" ]\n \
2 -> 3 [ label = \"\\\"RoleC?RoleB: i32\\\"\" ]\n \
3 -> 4 [ label = \"\\\"RoleC!RoleA: i32\\\"\" ]\n \
4 -> 5 [ label = \"\\\"RoleC?RoleA: i32\\\"\" ]\n \
5 -> 6 [ label = \"\\\"RoleC!RoleB: i32\\\"\" ]\n \
6 -> 7 [ label = \"\\\"0\\\"\" ]\n \
2 -> 8 [ label = \"\\\"0\\\"\" ]\n\
}\n"
);
assert_eq!(kmc, Some(1));
}