package object

import (
	

	
	
)

type bfsCommitIterator struct {
	seenExternal map[plumbing.Hash]bool
	seen         map[plumbing.Hash]bool
	queue        []*Commit
}
NewCommitIterBSF returns a CommitIter that walks the commit history, starting at the given commit and visiting its parents in pre-order. The given callback will be called for each visited commit. Each commit will be visited only once. If the callback returns an error, walking will stop and will return the error. Other errors might be returned if the history cannot be traversed (e.g. missing objects). Ignore allows to skip some commits from being iterated.
func (
	 *Commit,
	 map[plumbing.Hash]bool,
	 []plumbing.Hash,
) CommitIter {
	 := make(map[plumbing.Hash]bool)
	for ,  := range  {
		[] = true
	}

	return &bfsCommitIterator{
		seenExternal: ,
		seen:         ,
		queue:        []*Commit{},
	}
}

func ( *bfsCommitIterator) ( storer.EncodedObjectStorer,  plumbing.Hash) error {
	if .seen[] || .seenExternal[] {
		return nil
	}
	,  := GetCommit(, )
	if  != nil {
		return 
	}
	.queue = append(.queue, )
	return nil
}

func ( *bfsCommitIterator) () (*Commit, error) {
	var  *Commit
	for {
		if len(.queue) == 0 {
			return nil, io.EOF
		}
		 = .queue[0]
		.queue = .queue[1:]

		if .seen[.Hash] || .seenExternal[.Hash] {
			continue
		}

		.seen[.Hash] = true

		for ,  := range .ParentHashes {
			 := .appendHash(.s, )
			if  != nil {
				return nil, 
			}
		}

		return , nil
	}
}

func ( *bfsCommitIterator) ( func(*Commit) error) error {
	for {
		,  := .Next()
		if  == io.EOF {
			break
		}
		if  != nil {
			return 
		}

		 = ()
		if  == storer.ErrStop {
			break
		}
		if  != nil {
			return 
		}
	}

	return nil
}