1package bug
 2
 3import (
 4	"github.com/pkg/errors"
 5
 6	"github.com/git-bug/git-bug/entities/common"
 7	"github.com/git-bug/git-bug/entities/identity"
 8	"github.com/git-bug/git-bug/entity"
 9	"github.com/git-bug/git-bug/entity/dag"
10	"github.com/git-bug/git-bug/util/timestamp"
11)
12
13var _ Operation = &SetStatusOperation{}
14
15// SetStatusOperation will change the status of a bug
16type SetStatusOperation struct {
17	dag.OpBase
18	Status common.Status `json:"status"`
19}
20
21func (op *SetStatusOperation) Id() entity.Id {
22	return dag.IdOperation(op, &op.OpBase)
23}
24
25func (op *SetStatusOperation) Apply(snapshot *Snapshot) {
26	snapshot.Status = op.Status
27	snapshot.addActor(op.Author())
28
29	id := op.Id()
30	item := &SetStatusTimelineItem{
31		// id:         id,
32		combinedId: entity.CombineIds(snapshot.Id(), id),
33		Author:     op.Author(),
34		UnixTime:   timestamp.Timestamp(op.UnixTime),
35		Status:     op.Status,
36	}
37
38	snapshot.Timeline = append(snapshot.Timeline, item)
39}
40
41func (op *SetStatusOperation) Validate() error {
42	if err := op.OpBase.Validate(op, SetStatusOp); err != nil {
43		return err
44	}
45
46	if err := op.Status.Validate(); err != nil {
47		return errors.Wrap(err, "status")
48	}
49
50	return nil
51}
52
53func NewSetStatusOp(author identity.Interface, unixTime int64, status common.Status) *SetStatusOperation {
54	return &SetStatusOperation{
55		OpBase: dag.NewOpBase(SetStatusOp, author, unixTime),
56		Status: status,
57	}
58}
59
60type SetStatusTimelineItem struct {
61	combinedId entity.CombinedId
62	Author     identity.Interface
63	UnixTime   timestamp.Timestamp
64	Status     common.Status
65}
66
67func (s SetStatusTimelineItem) CombinedId() entity.CombinedId {
68	return s.combinedId
69}
70
71// IsAuthored is a sign post-method for gqlgen, to mark compliance to an interface.
72func (s *SetStatusTimelineItem) IsAuthored() {}
73
74// Open is a convenience function to change a bugs state to Open
75func Open(b Interface, author identity.Interface, unixTime int64, metadata map[string]string) (*SetStatusOperation, error) {
76	op := NewSetStatusOp(author, unixTime, common.OpenStatus)
77	for key, value := range metadata {
78		op.SetMetadata(key, value)
79	}
80	if err := op.Validate(); err != nil {
81		return nil, err
82	}
83	b.Append(op)
84	return op, nil
85}
86
87// Close is a convenience function to change a bugs state to Close
88func Close(b Interface, author identity.Interface, unixTime int64, metadata map[string]string) (*SetStatusOperation, error) {
89	op := NewSetStatusOp(author, unixTime, common.ClosedStatus)
90	for key, value := range metadata {
91		op.SetMetadata(key, value)
92	}
93	if err := op.Validate(); err != nil {
94		return nil, err
95	}
96	b.Append(op)
97	return op, nil
98}