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