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
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use crate::{
    controller::{Error, UserInteractionController},
    style,
};
use chain_impl_mockchain::certificate::VotePlan;
use clap::Parser;

#[derive(Parser, Debug)]
pub enum Describe {
    /// Prints available wallets with aliases
    /// that can be used
    Wallets(DescribeWallets),
    /// Prints available node with aliases
    /// that can be used
    Nodes(DescribeNodes),
    /// Prints trusted peer info
    Topology(DescribeTopology),
    /// Prints everything
    All(DescribeAll),
    /// Prints Votes Plan
    VotePlan(DescribeVotePlans),
}

impl Describe {
    pub fn exec(&self, controller: &mut UserInteractionController) -> Result<(), Error> {
        match self {
            Describe::Wallets(wallets) => wallets.exec(controller),
            Describe::Nodes(desc_nodes) => desc_nodes.exec(controller),
            Describe::All(all) => all.exec(controller),
            Describe::Topology(topology) => topology.exec(controller),
            Describe::VotePlan(vote_plans) => vote_plans.exec(controller),
        }
    }
}

#[derive(Parser, Debug)]
pub struct DescribeTopology {
    #[clap(short = 'a', long = "alias")]
    pub alias: Option<String>,
}

impl DescribeTopology {
    pub fn exec(&self, controller: &mut UserInteractionController) -> Result<(), Error> {
        println!(
            "{}",
            style::info.apply_to("Legend: '->' means trust direction".to_owned())
        );
        for (alias, node) in controller.controller().settings().nodes.iter() {
            println!(
                "\t{} -> {:?}",
                alias,
                node.node_topology
                    .trusted_peers
                    .iter()
                    .collect::<Vec<&String>>()
            )
        }
        Ok(())
    }
}

#[derive(Parser, Debug)]
pub struct DescribeWallets {
    #[clap(short = 'a', long = "alias")]
    pub alias: Option<String>,
}

impl DescribeWallets {
    pub fn exec(&self, controller: &mut UserInteractionController) -> Result<(), Error> {
        println!("Wallets:");
        for (alias, wallet) in controller.controller().defined_wallets() {
            println!(
                "\t{}: address: {}, initial_funds: {}, delegated to: {:?}",
                alias,
                wallet.address()?,
                wallet.template().value(),
                wallet.template().delegate()
            );
        }
        Ok(())
    }
}

#[derive(Parser, Debug)]
pub struct DescribeVotePlans {
    #[clap(short = 'a', long = "alias")]
    pub alias: Option<String>,
}

impl DescribeVotePlans {
    pub fn exec(&self, controller: &mut UserInteractionController) -> Result<(), Error> {
        println!("Vote Plans:");
        for vote_plan in controller.controller().defined_vote_plans() {
            let chain_vote_plan: VotePlan = vote_plan.clone().into();
            println!(
                "\t{}:\n\t - owner: {}\n\t - id: {}\n\t - start: {}\n\t - tally: {}\n\t - end: {}\n",
                vote_plan.alias(),
                vote_plan.owner(),
                vote_plan.id(),
                chain_vote_plan.vote_start(),
                chain_vote_plan.committee_start(),
                chain_vote_plan.committee_end()
            );
            println!("\tProposals");

            for proposal in vote_plan.proposals() {
                println!("\t\t{}", hex::encode(proposal.id()))
            }
        }
        Ok(())
    }
}
#[derive(Parser, Debug)]
pub struct DescribeNodes {
    #[clap(short = 'a', long = "alias")]
    pub alias: Option<String>,
}

impl DescribeNodes {
    pub fn exec(&self, controller: &mut UserInteractionController) -> Result<(), Error> {
        println!("Nodes:");
        for (alias, node) in controller.controller().defined_nodes() {
            println!("\t{}: rest api: {}", alias, node.config.rest.listen);
        }
        Ok(())
    }
}

#[derive(Parser, Debug)]
pub struct DescribeAll {
    #[clap(short = 'a', long = "alias")]
    pub alias: Option<String>,
}

impl DescribeAll {
    pub fn exec(&self, controller: &mut UserInteractionController) -> Result<(), Error> {
        let describe_wallets = DescribeWallets { alias: None };
        describe_wallets.exec(controller)?;
        let describe_nodes = DescribeNodes { alias: None };
        describe_nodes.exec(controller)
    }
}