package git

import (
	"bytes"
	"errors"
	"fmt"

	billy "gopkg.in/src-d/go-billy.v3"
	"gopkg.in/src-d/go-git.v4/config"
	"gopkg.in/src-d/go-git.v4/plumbing"
	"gopkg.in/src-d/go-git.v4/plumbing/format/index"
)

var (
	ErrSubmoduleAlreadyInitialized = errors.New("submodule already initialized")
	ErrSubmoduleNotInitialized     = errors.New("submodule not initialized")
)

// Submodule a submodule allows you to keep another Git repository in a
// subdirectory of your repository.
type Submodule struct {
	// initialized defines if a submodule was already initialized.
	initialized bool

	c *config.Submodule
	w *Worktree
}

// Config returns the submodule config
func (s *Submodule) Config() *config.Submodule {
	return s.c
}

// Init initialize the submodule reading the recorded Entry in the index for
// the given submodule
func (s *Submodule) Init() error {
	cfg, err := s.w.r.Storer.Config()
	if err != nil {
		return err
	}

	_, ok := cfg.Submodules[s.c.Name]
	if ok {
		return ErrSubmoduleAlreadyInitialized
	}

	s.initialized = true

	cfg.Submodules[s.c.Name] = s.c
	return s.w.r.Storer.SetConfig(cfg)
}

// Status returns the status of the submodule.
func (s *Submodule) Status() (*SubmoduleStatus, error) {
	idx, err := s.w.r.Storer.Index()
	if err != nil {
		return nil, err
	}

	return s.status(idx)
}

func (s *Submodule) status(idx *index.Index) (*SubmoduleStatus, error) {
	e, err := idx.Entry(s.c.Path)
	if err != nil {
		return nil, err
	}

	status := &SubmoduleStatus{
		Path:     s.c.Path,
		Expected: e.Hash,
	}

	if !s.initialized {
		return status, nil
	}

	r, err := s.Repository()
	if err != nil {
		return nil, err
	}

	head, err := r.Head()
	if err == nil {
		status.Current = head.Hash()
	}

	if err != nil && err == plumbing.ErrReferenceNotFound {
		err = nil
	}

	return status, err
}

// Repository returns the Repository represented by this submodule
func (s *Submodule) Repository() (*Repository, error) {
	if !s.initialized {
		return nil, ErrSubmoduleNotInitialized
	}

	storer, err := s.w.r.Storer.Module(s.c.Name)
	if err != nil {
		return nil, err
	}

	_, err = storer.Reference(plumbing.HEAD)
	if err != nil && err != plumbing.ErrReferenceNotFound {
		return nil, err
	}

	var exists bool
	if err == nil {
		exists = true
	}

	var worktree billy.Filesystem
	if worktree, err = s.w.fs.Chroot(s.c.Path); err != nil {
		return nil, err
	}

	if exists {
		return Open(storer, worktree)
	}

	r, err := Init(storer, worktree)
	if err != nil {
		return nil, err
	}

	_, err = r.CreateRemote(&config.RemoteConfig{
		Name: DefaultRemoteName,
		URL:  s.c.URL,
	})

	return r, err
}

// Update the registered submodule to match what the superproject expects, the
// submodule should be initialized first calling the Init method or setting in
// the options SubmoduleUpdateOptions.Init equals true
func (s *Submodule) Update(o *SubmoduleUpdateOptions) error {
	return s.update(o, plumbing.ZeroHash)
}

func (s *Submodule) update(o *SubmoduleUpdateOptions, forceHash plumbing.Hash) error {
	if !s.initialized && !o.Init {
		return ErrSubmoduleNotInitialized
	}

	if !s.initialized && o.Init {
		if err := s.Init(); err != nil {
			return err
		}
	}

	idx, err := s.w.r.Storer.Index()
	if err != nil {
		return err
	}

	hash := forceHash
	if hash.IsZero() {
		e, err := idx.Entry(s.c.Path)
		if err != nil {
			return err
		}

		hash = e.Hash
	}

	r, err := s.Repository()
	if err != nil {
		return err
	}

	if err := s.fetchAndCheckout(r, o, hash); err != nil {
		return err
	}

	return s.doRecursiveUpdate(r, o)
}

func (s *Submodule) doRecursiveUpdate(r *Repository, o *SubmoduleUpdateOptions) error {
	if o.RecurseSubmodules == NoRecurseSubmodules {
		return nil
	}

	w, err := r.Worktree()
	if err != nil {
		return err
	}

	l, err := w.Submodules()
	if err != nil {
		return err
	}

	new := &SubmoduleUpdateOptions{}
	*new = *o

	new.RecurseSubmodules--
	return l.Update(new)
}

func (s *Submodule) fetchAndCheckout(r *Repository, o *SubmoduleUpdateOptions, hash plumbing.Hash) error {
	if !o.NoFetch {
		err := r.Fetch(&FetchOptions{})
		if err != nil && err != NoErrAlreadyUpToDate {
			return err
		}
	}

	w, err := r.Worktree()
	if err != nil {
		return err
	}

	if err := w.Checkout(&CheckoutOptions{Hash: hash}); err != nil {
		return err
	}

	head := plumbing.NewHashReference(plumbing.HEAD, hash)
	return r.Storer.SetReference(head)
}

// Submodules list of several submodules from the same repository.
type Submodules []*Submodule

// Init initializes the submodules in this list.
func (s Submodules) Init() error {
	for _, sub := range s {
		if err := sub.Init(); err != nil {
			return err
		}
	}

	return nil
}

// Update updates all the submodules in this list.
func (s Submodules) Update(o *SubmoduleUpdateOptions) error {
	for _, sub := range s {
		if err := sub.Update(o); err != nil {
			return err
		}
	}

	return nil
}

// Status returns the status of the submodules.
func (s Submodules) Status() (SubmodulesStatus, error) {
	var list SubmodulesStatus

	var r *Repository
	for _, sub := range s {
		if r == nil {
			r = sub.w.r
		}

		idx, err := r.Storer.Index()
		if err != nil {
			return nil, err
		}

		status, err := sub.status(idx)
		if err != nil {
			return nil, err
		}

		list = append(list, status)
	}

	return list, nil
}

// SubmodulesStatus contains the status for all submodiles in the worktree
type SubmodulesStatus []*SubmoduleStatus

// String is equivalent to `git submodule status`
func (s SubmodulesStatus) String() string {
	buf := bytes.NewBuffer(nil)
	for _, sub := range s {
		fmt.Fprintln(buf, sub)
	}

	return buf.String()
}

// SubmoduleStatus contains the status for a submodule in the worktree
type SubmoduleStatus struct {
	Path     string
	Current  plumbing.Hash
	Expected plumbing.Hash
	Branch   plumbing.ReferenceName
}

// IsClean is the HEAD of the submodule is equals to the expected commit
func (s *SubmoduleStatus) IsClean() bool {
	return s.Current == s.Expected
}

// String is equivalent to `git submodule status <submodule>`
//
// This will print the SHA-1 of the currently checked out commit for a
// submodule, along with the submodule path and the output of git describe fo
// the SHA-1. Each SHA-1 will be prefixed with - if the submodule is not
// initialized, + if the currently checked out submodule commit does not match
// the SHA-1 found in the index of the containing repository.
func (s *SubmoduleStatus) String() string {
	var extra string
	var status = ' '

	if s.Current.IsZero() {
		status = '-'
	} else if !s.IsClean() {
		status = '+'
	}

	if len(s.Branch) != 0 {
		extra = string(s.Branch[5:])
	} else if !s.Current.IsZero() {
		extra = s.Current.String()[:7]
	}

	if extra != "" {
		extra = fmt.Sprintf(" (%s)", extra)
	}

	return fmt.Sprintf("%c%s %s%s", status, s.Expected, s.Path, extra)
}
