1package bug
2
3import (
4 "fmt"
5 "time"
6
7 "github.com/MichaelMure/git-bug/entities/common"
8 "github.com/MichaelMure/git-bug/entities/identity"
9 "github.com/MichaelMure/git-bug/entity"
10)
11
12// var _ entity.Snapshot = &Snapshot{}
13
14// Snapshot is a compiled form of the Bug data structure used for storage and merge
15type Snapshot struct {
16 id entity.Id
17
18 Status common.Status
19 Title string
20 Comments []Comment
21 Labels []Label
22 Author identity.Interface
23 Actors []identity.Interface
24 Participants []identity.Interface
25 CreateTime time.Time
26
27 Timeline []TimelineItem
28
29 Operations []Operation
30}
31
32// Id returns the Bug identifier
33func (snap *Snapshot) Id() entity.Id {
34 if snap.id == "" {
35 // simply panic as it would be a coding error (no id provided at construction)
36 panic("no id")
37 }
38 return snap.id
39}
40
41func (snap *Snapshot) AllOperations() []Operation {
42 return snap.Operations
43}
44
45func (snap *Snapshot) AppendOperation(op Operation) {
46 snap.Operations = append(snap.Operations, op)
47}
48
49// EditTime returns the last time a bug was modified
50func (snap *Snapshot) EditTime() time.Time {
51 if len(snap.Operations) == 0 {
52 return time.Unix(0, 0)
53 }
54
55 return snap.Operations[len(snap.Operations)-1].Time()
56}
57
58// GetCreateMetadata return the creation metadata
59func (snap *Snapshot) GetCreateMetadata(key string) (string, bool) {
60 return snap.Operations[0].GetMetadata(key)
61}
62
63// SearchTimelineItem will search in the timeline for an item matching the given hash
64func (snap *Snapshot) SearchTimelineItem(id entity.CombinedId) (TimelineItem, error) {
65 for i := range snap.Timeline {
66 if snap.Timeline[i].CombinedId() == id {
67 return snap.Timeline[i], nil
68 }
69 }
70
71 return nil, fmt.Errorf("timeline item not found")
72}
73
74// SearchComment will search for a comment matching the given id
75func (snap *Snapshot) SearchComment(id entity.CombinedId) (*Comment, error) {
76 for _, c := range snap.Comments {
77 if c.combinedId == id {
78 return &c, nil
79 }
80 }
81
82 return nil, fmt.Errorf("comment not found")
83}
84
85// SearchCommentByOpId will search for a comment generated by the given operation Id
86func (snap *Snapshot) SearchCommentByOpId(id entity.Id) (*Comment, error) {
87 for _, c := range snap.Comments {
88 if c.targetId == id {
89 return &c, nil
90 }
91 }
92
93 return nil, fmt.Errorf("comment not found")
94}
95
96// append the operation author to the actors list
97func (snap *Snapshot) addActor(actor identity.Interface) {
98 for _, a := range snap.Actors {
99 if actor.Id() == a.Id() {
100 return
101 }
102 }
103
104 snap.Actors = append(snap.Actors, actor)
105}
106
107// append the operation author to the participants list
108func (snap *Snapshot) addParticipant(participant identity.Interface) {
109 for _, p := range snap.Participants {
110 if participant.Id() == p.Id() {
111 return
112 }
113 }
114
115 snap.Participants = append(snap.Participants, participant)
116}
117
118// HasParticipant return true if the id is a participant
119func (snap *Snapshot) HasParticipant(id entity.Id) bool {
120 for _, p := range snap.Participants {
121 if p.Id() == id {
122 return true
123 }
124 }
125 return false
126}
127
128// HasAnyParticipant return true if one of the ids is a participant
129func (snap *Snapshot) HasAnyParticipant(ids ...entity.Id) bool {
130 for _, id := range ids {
131 if snap.HasParticipant(id) {
132 return true
133 }
134 }
135 return false
136}
137
138// HasActor return true if the id is a actor
139func (snap *Snapshot) HasActor(id entity.Id) bool {
140 for _, p := range snap.Actors {
141 if p.Id() == id {
142 return true
143 }
144 }
145 return false
146}
147
148// HasAnyActor return true if one of the ids is a actor
149func (snap *Snapshot) HasAnyActor(ids ...entity.Id) bool {
150 for _, id := range ids {
151 if snap.HasActor(id) {
152 return true
153 }
154 }
155 return false
156}
157
158// IsAuthored is a sign post method for gqlgen
159func (snap *Snapshot) IsAuthored() {}