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