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
143
144
use std::collections::{HashMap, HashSet};
use itertools::Itertools;
use prost::{DecodeError, Message};
use crate::{EasyJson, error_info, HashClear, ProtoHashable, Response, response_metadata, ResponseMetadata, SafeOption};
use crate::structs::{AboutNodeResponse, ControlResponse, ErrorInfo, NodeMetadata, Proof, PublicKey, QueryTransactionResponse, State, SubmitTransactionResponse};

impl AboutNodeResponse {
    pub fn empty() -> Self {
        AboutNodeResponse::default()
    }
}

impl HashClear for Response {
    fn hash_clear(&mut self) {
        self.proof = None;
    }
}

impl Response {
    pub fn serialize(&self) -> Vec<u8> {
        return self.encode_to_vec();
    }

    pub fn deserialize(bytes: Vec<u8>) -> Result<Self, DecodeError> {
        return Response::decode(&*bytes);
    }

    pub fn empty_success() -> Response {
        let mut response = Response::default();
        response.response_metadata = response_metadata();
        response
    }

    pub fn from_error_info(error_info: ErrorInfo) -> Response {
        let mut r = Response::empty_success();
        let mut rm = response_metadata().expect("m");
        rm.success = false;
        rm.error_info = Some(error_info);
        r.response_metadata = Some(rm);
        return r.clone();
    }

    pub fn with_metadata(&mut self, node_metadata: NodeMetadata) -> &mut Response {
        self.node_metadata = Some(node_metadata);
        self
    }


    pub fn as_error_info(&self) -> Result<(), ErrorInfo> {
        let res = self.response_metadata.safe_get()?;
        if let Some(e) = &res.error_info {
            return Err(e.clone());
        }
        Ok(())
    }

    pub fn with_error_info(&self) -> Result<&Self, ErrorInfo> {
        let res = self.response_metadata.safe_get()?;
        if let Some(e) = &res.error_info {
            return Err(e.clone());
        }
        Ok(self)
    }


}


impl ControlResponse {
    pub fn empty() -> Self {
        Self {
            response_metadata: response_metadata(),
            control_multiparty_keygen_response: None,
            control_multiparty_signing_response: None,
        }
    }

    // TODO: Trait duplicate
    pub fn as_error_info(&self) -> Result<(), ErrorInfo> {
        let res = self.response_metadata.safe_get()?;
        if let Some(e) = &res.error_info {
            return Err(e.clone());
        }
        Ok(())
    }
}


impl QueryTransactionResponse {

}

impl SubmitTransactionResponse {
    pub fn accepted(&self, expected_count: usize) -> Result<(), ErrorInfo> {
        self.check_by_state(expected_count, State::Accepted)
    }
    pub fn pending(&self, expected_count: usize) -> Result<(), ErrorInfo> {
        self.check_by_state(expected_count, State::Pending)
    }
    pub fn check_by_state(&self, expected_count: usize, state: State) -> Result<(), ErrorInfo> {
        let accepted_count = self.unique_by_state()?.iter().filter(|(_, s)| *s == state as i32).count();
        if accepted_count >= expected_count {
            Ok(())
        } else {
            Err(error_info(format!("not enough {} observations, expected {}, got {}",
                                   state.json_or(), expected_count, accepted_count)))
        }
    }
    pub fn unique_by_state(&self) -> Result<HashSet<(&PublicKey, i32)>, ErrorInfo> {
        let mut results = HashSet::new();
        for p in &self.query_transaction_response
            .safe_get()?
            .observation_proofs {
            let state = p.metadata.safe_get()?.state;
            let pk = p.proof.safe_get()?.public_key.safe_get()?;
            results.insert((pk, state));
        }
        Ok(results)
    }

    pub fn count_unique_by_state(&self) -> Result<HashMap<i32, usize>, ErrorInfo> {
        let map: HashMap<i32, usize> = self.unique_by_state()?.iter().map(|(_, y)| y.clone()).counts();
        Ok(map)
    }


    pub fn at_least_1(&self) -> Result<(), ErrorInfo> {
        self.at_least_n(1)
    }

    pub fn at_least_n(&self, n: usize) -> Result<(), ErrorInfo> {
        self.accepted(n)?;
        self.pending(n)
    }
}

impl ResponseMetadata {
    pub fn from_error(error: ErrorInfo) -> Self {
        let mut rm = response_metadata().expect("m");
        rm.success = false;
        rm.error_info = Some(error);
        rm
    }
}