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
use chrono::Utc;

use super::file::{
    Allocation, AllocationRequest, AllocationRequestType, Allocations, Notaries, Notary,
};

impl Default for Notaries {
    fn default() -> Self {
        Self(vec![])
    }
}

impl Notaries {
    pub fn add(&self, signer: Notary) -> Self {
        let mut res = self.0.clone();
        res.push(signer);
        Self(res)
    }
}

impl AllocationRequest {
    pub fn new(
        actor: String,
        id: String,
        kind: AllocationRequestType,
        allocation_amount: String,
    ) -> Self {
        Self {
            actor,
            id,
            kind,
            allocation_amount,
            is_active: true,
        }
    }
}

impl Allocation {
    pub fn new(request_information: AllocationRequest) -> Self {
        Self {
            id: request_information.id,
            request_type: request_information.kind.to_string(),
            created_at: Utc::now().to_string(),
            updated_at: Utc::now().to_string(),
            is_active: true,
            amount: request_information.allocation_amount,
            signers: Notaries::default(),
        }
    }
}

impl Default for Allocations {
    fn default() -> Self {
        Self(vec![])
    }
}

impl Allocations {
    pub fn init(request_information: AllocationRequest) -> Self {
        let allocation = Allocation::new(request_information);
        Self(vec![allocation])
    }

    // should be changed to option
    pub fn active(&self) -> Option<Allocation> {
        let curr: Vec<Allocation> = self.0.clone();
        let mut allocation: Option<Allocation> = None;
        for alloc in curr.iter() {
            if alloc.is_active {
                allocation = Some(alloc.clone());
                break;
            }
        }
        allocation
    }

    // should be changed to option
    pub fn find_one(&self, request_id: String) -> Option<Allocation> {
        let curr: Vec<Allocation> = self.0.clone();
        let mut allocation: Option<Allocation> = None;
        for alloc in curr.iter() {
            if alloc.id == request_id {
                allocation = Some(alloc.clone());
                break;
            }
        }
        allocation
    }

    // should be changed to option
    pub fn is_active(&self, request_id: String) -> bool {
        let curr: Vec<Allocation> = self.0.clone();
        let mut is_active = false;
        for alloc in curr.iter() {
            if alloc.id == request_id {
                is_active = alloc.is_active;
                break;
            }
        }
        is_active
    }

    pub fn add_signer(&self, request_id: String, signer: Notary) -> Self {
        let mut res: Vec<Allocation> = self.0.clone();
        for allocation in res.iter_mut() {
            if allocation.id == request_id && allocation.is_active {
                allocation.signers = allocation.signers.add(signer);
                break;
            }
        }
        Self(res)
    }

    pub fn add_signer_and_complete(&self, request_id: String, signer: Notary) -> Self {
        let mut res: Vec<Allocation> = self.0.clone();
        for allocation in res.iter_mut() {
            if allocation.id == request_id && allocation.is_active {
                allocation.signers = allocation.signers.add(signer);
                allocation.is_active = false;
                break;
            }
        }
        Self(res)
    }

    pub fn complete_allocation(&self, request_id: String) -> Self {
        let mut res: Vec<Allocation> = self.0.clone();
        for allocation in res.iter_mut() {
            if allocation.id == request_id && allocation.is_active {
                allocation.is_active = false;
            }
        }
        Self(res)
    }

    pub fn push(&mut self, request: AllocationRequest) -> Self {
        let allocation = Allocation::new(request);
        self.0.push(allocation);
        self.clone()
    }
}