package object

import (
	"io"

	"gopkg.in/src-d/go-git.v4/plumbing/storer"
)

type commitFileIter struct {
	fileName      string
	sourceIter    CommitIter
	currentCommit *Commit
	all           bool
}

// NewCommitFileIterFromIter returns a commit iterator which performs diffTree between
// successive trees returned from the commit iterator from the argument. The purpose of this is
// to find the commits that explain how the files that match the path came to be.
func NewCommitFileIterFromIter(fileName string, commitIter CommitIter, all bool) CommitIter {
	iterator := new(commitFileIter)
	iterator.sourceIter = commitIter
	iterator.fileName = fileName
	iterator.all = all
	return iterator
}

func (c *commitFileIter) Next() (*Commit, error) {
	if c.currentCommit == nil {
		var err error
		c.currentCommit, err = c.sourceIter.Next()
		if err != nil {
			return nil, err
		}
	}
	commit, commitErr := c.getNextFileCommit()

	// Setting current-commit to nil to prevent unwanted states when errors are raised
	if commitErr != nil {
		c.currentCommit = nil
	}
	return commit, commitErr
}

func (c *commitFileIter) getNextFileCommit() (*Commit, error) {
	for {
		// Parent-commit can be nil if the current-commit is the initial commit
		parentCommit, parentCommitErr := c.sourceIter.Next()
		if parentCommitErr != nil {
			// If the parent-commit is beyond the initial commit, keep it nil
			if parentCommitErr != io.EOF {
				return nil, parentCommitErr
			}
			parentCommit = nil
		}

		// Fetch the trees of the current and parent commits
		currentTree, currTreeErr := c.currentCommit.Tree()
		if currTreeErr != nil {
			return nil, currTreeErr
		}

		var parentTree *Tree
		if parentCommit != nil {
			var parentTreeErr error
			parentTree, parentTreeErr = parentCommit.Tree()
			if parentTreeErr != nil {
				return nil, parentTreeErr
			}
		}

		// Find diff between current and parent trees
		changes, diffErr := DiffTree(currentTree, parentTree)
		if diffErr != nil {
			return nil, diffErr
		}

		foundChangeForFile := false
		for _, change := range changes {
			if change.name() != c.fileName {
				continue
			}

			// filename matches, now check if source iterator contains all commits (from all refs)
			if c.all {
				// for `git log --all` also check if the next commit comes from the same parent
				for _, h := range c.currentCommit.ParentHashes {
					if h == parentCommit.Hash {
						foundChangeForFile = true
						break
					}
				}
			} else {
				foundChangeForFile = true
			}

			if foundChangeForFile {
				break
			}
		}

		// Storing the current-commit in-case a change is found, and
		// Updating the current-commit for the next-iteration
		prevCommit := c.currentCommit
		c.currentCommit = parentCommit

		if foundChangeForFile == true {
			return prevCommit, nil
		}

		// If not matches found and if parent-commit is beyond the initial commit, then return with EOF
		if parentCommit == nil {
			return nil, io.EOF
		}
	}
}

func (c *commitFileIter) ForEach(cb func(*Commit) error) error {
	for {
		commit, nextErr := c.Next()
		if nextErr != nil {
			return nextErr
		}
		err := cb(commit)
		if err == storer.ErrStop {
			return nil
		} else if err != nil {
			return err
		}
	}
}

func (c *commitFileIter) Close() {
	c.sourceIter.Close()
}
