package object

import (
	"bytes"
	"io"
	"strings"

	"gopkg.in/src-d/go-git.v4/plumbing/filemode"
	"gopkg.in/src-d/go-git.v4/plumbing/storer"
	"gopkg.in/src-d/go-git.v4/utils/binary"
	"gopkg.in/src-d/go-git.v4/utils/ioutil"
)

// File represents git file objects.
type File struct {
	// Name is the path of the file. It might be relative to a tree,
	// depending of the function that generates it.
	Name string
	// Mode is the file mode.
	Mode filemode.FileMode
	// Blob with the contents of the file.
	Blob
}

// NewFile returns a File based on the given blob object
func NewFile(name string, m filemode.FileMode, b *Blob) *File {
	return &File{Name: name, Mode: m, Blob: *b}
}

// Contents returns the contents of a file as a string.
func (f *File) Contents() (content string, err error) {
	reader, err := f.Reader()
	if err != nil {
		return "", err
	}
	defer ioutil.CheckClose(reader, &err)

	buf := new(bytes.Buffer)
	if _, err := buf.ReadFrom(reader); err != nil {
		return "", err
	}

	return buf.String(), nil
}

// IsBinary returns if the file is binary or not
func (f *File) IsBinary() (bin bool, err error) {
	reader, err := f.Reader()
	if err != nil {
		return false, err
	}
	defer ioutil.CheckClose(reader, &err)

	return binary.IsBinary(reader)
}

// Lines returns a slice of lines from the contents of a file, stripping
// all end of line characters. If the last line is empty (does not end
// in an end of line), it is also stripped.
func (f *File) Lines() ([]string, error) {
	content, err := f.Contents()
	if err != nil {
		return nil, err
	}

	splits := strings.Split(content, "\n")
	// remove the last line if it is empty
	if splits[len(splits)-1] == "" {
		return splits[:len(splits)-1], nil
	}

	return splits, nil
}

// FileIter provides an iterator for the files in a tree.
type FileIter struct {
	s storer.EncodedObjectStorer
	w TreeWalker
}

// NewFileIter takes a storer.EncodedObjectStorer and a Tree and returns a
// *FileIter that iterates over all files contained in the tree, recursively.
func NewFileIter(s storer.EncodedObjectStorer, t *Tree) *FileIter {
	return &FileIter{s: s, w: *NewTreeWalker(t, true, nil)}
}

// Next moves the iterator to the next file and returns a pointer to it. If
// there are no more files, it returns io.EOF.
func (iter *FileIter) Next() (*File, error) {
	for {
		name, entry, err := iter.w.Next()
		if err != nil {
			return nil, err
		}

		if entry.Mode == filemode.Dir || entry.Mode == filemode.Submodule {
			continue
		}

		blob, err := GetBlob(iter.s, entry.Hash)
		if err != nil {
			return nil, err
		}

		return NewFile(name, entry.Mode, blob), nil
	}
}

// ForEach call the cb function for each file contained in this iter until
// an error happens or the end of the iter is reached. If plumbing.ErrStop is sent
// the iteration is stop but no error is returned. The iterator is closed.
func (iter *FileIter) ForEach(cb func(*File) error) error {
	defer iter.Close()

	for {
		f, err := iter.Next()
		if err != nil {
			if err == io.EOF {
				return nil
			}

			return err
		}

		if err := cb(f); err != nil {
			if err == storer.ErrStop {
				return nil
			}

			return err
		}
	}
}

func (iter *FileIter) Close() {
	iter.w.Close()
}
