aboutsummaryrefslogblamecommitdiffstats
path: root/bug/bug.go
blob: b36246e3b3c320ae5952168158eea7e7f163ddde (plain) (tree)
1
2

           
















                                                                 
 
 

















                                         
                                                         









                                        






                                              
                                               

                                                         






























                                                  













                                                    
package bug

import (
	"github.com/kevinburke/go.uuid"
)

// Bug hold the data of a bug thread, organized in a way close to
// how it will be persisted inside Git. This is the datastructure
// used for merge of two different version.
type Bug struct {
	// Id used as unique identifier
	Id uuid.UUID

	// TODO: need a way to order bugs
	// Probably a Lamport clock

	Packs []OperationPack

	Staging OperationPack
}

// Create a new Bug
func NewBug() (*Bug, error) {

	// Creating UUID Version 4
	id, err := uuid.ID4()

	if err != nil {
		return nil, err
	}

	return &Bug{
		Id: id,
	}, nil
}

// IsValid check if the Bug data is valid
func (bug *Bug) IsValid() bool {
	// non-empty
	if len(bug.Packs) == 0 && bug.Staging.IsEmpty() {
		return false
	}

	// check if each pack is valid
	for _, pack := range bug.Packs {
		if !pack.IsValid() {
			return false
		}
	}

	// check if Staging is valid if needed
	if !bug.Staging.IsEmpty() {
		if !bug.Staging.IsValid() {
			return false
		}
	}

	// The very first Op should be a CREATE
	firstOp := bug.firstOp()
	if firstOp == nil || firstOp.OpType() != CREATE {
		return false
	}

	// Check that there is no more CREATE op
	it := NewOperationIterator(bug)
	createCount := 0
	for it.Next() {
		if it.Value().OpType() == CREATE {
			createCount++
		}
	}

	if createCount != 1 {
		return false
	}

	return true
}

func (bug *Bug) Append(op Operation) {
	bug.Staging.Append(op)
}

func (bug *Bug) Commit() {
	bug.Packs = append(bug.Packs, bug.Staging)
	bug.Staging = OperationPack{}
}

func (bug *Bug) HumanId() string {
	return bug.Id.String()
}

func (bug *Bug) firstOp() Operation {
	for _, pack := range bug.Packs {
		for _, op := range pack.Operations {
			return op
		}
	}

	if !bug.Staging.IsEmpty() {
		return bug.Staging.Operations[0]
	}

	return nil
}