package git

/*
#include <git2.h>
*/
import "C"
import (
	"runtime"
	"unsafe"
)

type ReferenceType int

const (
	ReferenceSymbolic ReferenceType = C.GIT_REF_SYMBOLIC
	ReferenceOid      ReferenceType = C.GIT_REF_OID
)

type Reference struct {
	ptr  *C.git_reference
	repo *Repository
}

type ReferenceCollection struct {
	repo *Repository
}

func (c *ReferenceCollection) Lookup(name string) (*Reference, error) {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))
	var ptr *C.git_reference

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_reference_lookup(&ptr, c.repo.ptr, cname)
	runtime.KeepAlive(c)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return newReferenceFromC(ptr, c.repo), nil
}

func (c *ReferenceCollection) Create(name string, id *Oid, force bool, msg string) (*Reference, error) {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	var cmsg *C.char
	if msg == "" {
		cmsg = nil
	} else {
		cmsg = C.CString(msg)
		defer C.free(unsafe.Pointer(cmsg))
	}

	var ptr *C.git_reference

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_reference_create(&ptr, c.repo.ptr, cname, id.toC(), cbool(force), cmsg)
	runtime.KeepAlive(c)
	runtime.KeepAlive(id)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return newReferenceFromC(ptr, c.repo), nil
}

func (c *ReferenceCollection) CreateSymbolic(name, target string, force bool, msg string) (*Reference, error) {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	ctarget := C.CString(target)
	defer C.free(unsafe.Pointer(ctarget))

	var cmsg *C.char
	if msg == "" {
		cmsg = nil
	} else {
		cmsg = C.CString(msg)
		defer C.free(unsafe.Pointer(cmsg))
	}

	var ptr *C.git_reference

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_reference_symbolic_create(&ptr, c.repo.ptr, cname, ctarget, cbool(force), cmsg)
	runtime.KeepAlive(c)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return newReferenceFromC(ptr, c.repo), nil
}

// EnsureLog ensures that there is a reflog for the given reference
// name and creates an empty one if necessary.
func (c *ReferenceCollection) EnsureLog(name string) error {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_ensure_log(c.repo.ptr, cname)
	runtime.KeepAlive(c)
	if ret < 0 {
		return MakeGitError(ret)
	}

	return nil
}

// HasLog returns whether there is a reflog for the given reference
// name
func (c *ReferenceCollection) HasLog(name string) (bool, error) {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_has_log(c.repo.ptr, cname)
	runtime.KeepAlive(c)
	if ret < 0 {
		return false, MakeGitError(ret)
	}

	return ret == 1, nil
}

// Dwim looks up a reference by DWIMing its short name
func (c *ReferenceCollection) Dwim(name string) (*Reference, error) {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var ptr *C.git_reference
	ret := C.git_reference_dwim(&ptr, c.repo.ptr, cname)
	runtime.KeepAlive(c)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newReferenceFromC(ptr, c.repo), nil
}

func newReferenceFromC(ptr *C.git_reference, repo *Repository) *Reference {
	ref := &Reference{ptr: ptr, repo: repo}
	runtime.SetFinalizer(ref, (*Reference).Free)
	return ref
}

func (v *Reference) SetSymbolicTarget(target string, msg string) (*Reference, error) {
	var ptr *C.git_reference

	ctarget := C.CString(target)
	defer C.free(unsafe.Pointer(ctarget))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var cmsg *C.char
	if msg == "" {
		cmsg = nil
	} else {
		cmsg = C.CString(msg)
		defer C.free(unsafe.Pointer(cmsg))
	}

	ret := C.git_reference_symbolic_set_target(&ptr, v.ptr, ctarget, cmsg)
	runtime.KeepAlive(v)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newReferenceFromC(ptr, v.repo), nil
}

func (v *Reference) SetTarget(target *Oid, msg string) (*Reference, error) {
	var ptr *C.git_reference

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	var cmsg *C.char
	if msg == "" {
		cmsg = nil
	} else {
		cmsg = C.CString(msg)
		defer C.free(unsafe.Pointer(cmsg))
	}

	ret := C.git_reference_set_target(&ptr, v.ptr, target.toC(), cmsg)
	runtime.KeepAlive(v)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newReferenceFromC(ptr, v.repo), nil
}

func (v *Reference) Resolve() (*Reference, error) {
	var ptr *C.git_reference

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_resolve(&ptr, v.ptr)
	runtime.KeepAlive(v)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newReferenceFromC(ptr, v.repo), nil
}

func (v *Reference) Rename(name string, force bool, msg string) (*Reference, error) {
	var ptr *C.git_reference
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))

	var cmsg *C.char
	if msg == "" {
		cmsg = nil
	} else {
		cmsg = C.CString(msg)
		defer C.free(unsafe.Pointer(cmsg))
	}

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_rename(&ptr, v.ptr, cname, cbool(force), cmsg)
	runtime.KeepAlive(v)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newReferenceFromC(ptr, v.repo), nil
}

func (v *Reference) Target() *Oid {
	ret := newOidFromC(C.git_reference_target(v.ptr))
	runtime.KeepAlive(v)
	return ret
}

func (v *Reference) SymbolicTarget() string {
	var ret string
	cstr := C.git_reference_symbolic_target(v.ptr)

	if cstr != nil {
		return C.GoString(cstr)
	}

	runtime.KeepAlive(v)
	return ret
}

func (v *Reference) Delete() error {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_delete(v.ptr)
	runtime.KeepAlive(v)
	if ret < 0 {
		return MakeGitError(ret)
	}

	return nil
}

func (v *Reference) Peel(t ObjectType) (*Object, error) {
	var cobj *C.git_object

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	err := C.git_reference_peel(&cobj, v.ptr, C.git_otype(t))
	runtime.KeepAlive(v)
	if err < 0 {
		return nil, MakeGitError(err)
	}

	return allocObject(cobj, v.repo), nil
}

// Owner returns a weak reference to the repository which owns this
// reference.
func (v *Reference) Owner() *Repository {
	return &Repository{
		ptr: C.git_reference_owner(v.ptr),
	}
}

// Cmp compares both references, retursn 0 on equality, otherwise a
// stable sorting.
func (v *Reference) Cmp(ref2 *Reference) int {
	ret := int(C.git_reference_cmp(v.ptr, ref2.ptr))
	runtime.KeepAlive(v)
	runtime.KeepAlive(ref2)
	return ret
}

// Shorthand ret :=s a "human-readable" short reference name
func (v *Reference) Shorthand() string {
	ret := C.GoString(C.git_reference_shorthand(v.ptr))
	runtime.KeepAlive(v)
	return ret
}

func (v *Reference) Name() string {
	ret := C.GoString(C.git_reference_name(v.ptr))
	runtime.KeepAlive(v)
	return ret
}

func (v *Reference) Type() ReferenceType {
	ret := ReferenceType(C.git_reference_type(v.ptr))
	runtime.KeepAlive(v)
	return ret
}

func (v *Reference) IsBranch() bool {
	ret := C.git_reference_is_branch(v.ptr) == 1
	runtime.KeepAlive(v)
	return ret
}

func (v *Reference) IsRemote() bool {
	ret := C.git_reference_is_remote(v.ptr) == 1
	runtime.KeepAlive(v)
	return ret
}

func (v *Reference) IsTag() bool {
	ret := C.git_reference_is_tag(v.ptr) == 1
	runtime.KeepAlive(v)
	return ret
}

// IsNote checks if the reference is a note.
func (v *Reference) IsNote() bool {
	ret := C.git_reference_is_note(v.ptr) == 1
	runtime.KeepAlive(v)
	return ret
}

func (v *Reference) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_reference_free(v.ptr)
}

type ReferenceIterator struct {
	ptr  *C.git_reference_iterator
	repo *Repository
}

type ReferenceNameIterator struct {
	*ReferenceIterator
}

// NewReferenceIterator creates a new iterator over reference names
func (repo *Repository) NewReferenceIterator() (*ReferenceIterator, error) {
	var ptr *C.git_reference_iterator

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_iterator_new(&ptr, repo.ptr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newReferenceIteratorFromC(ptr, repo), nil
}

// NewReferenceIterator creates a new branch iterator over reference names
func (repo *Repository) NewReferenceNameIterator() (*ReferenceNameIterator, error) {
	var ptr *C.git_reference_iterator

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_iterator_new(&ptr, repo.ptr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	iter := newReferenceIteratorFromC(ptr, repo)
	return iter.Names(), nil
}

// NewReferenceIteratorGlob creates an iterator over reference names
// that match the speicified glob. The glob is of the usual fnmatch
// type.
func (repo *Repository) NewReferenceIteratorGlob(glob string) (*ReferenceIterator, error) {
	cstr := C.CString(glob)
	defer C.free(unsafe.Pointer(cstr))
	var ptr *C.git_reference_iterator

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_iterator_glob_new(&ptr, repo.ptr, cstr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newReferenceIteratorFromC(ptr, repo), nil
}

func (i *ReferenceIterator) Names() *ReferenceNameIterator {
	return &ReferenceNameIterator{i}
}

// NextName retrieves the next reference name. If the iteration is over,
// the returned error is git.ErrIterOver
func (v *ReferenceNameIterator) Next() (string, error) {
	var ptr *C.char

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_next_name(&ptr, v.ptr)
	if ret < 0 {
		return "", MakeGitError(ret)
	}

	return C.GoString(ptr), nil
}

// Next retrieves the next reference. If the iterationis over, the
// returned error is git.ErrIterOver
func (v *ReferenceIterator) Next() (*Reference, error) {
	var ptr *C.git_reference

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_reference_next(&ptr, v.ptr)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newReferenceFromC(ptr, v.repo), nil
}

func newReferenceIteratorFromC(ptr *C.git_reference_iterator, r *Repository) *ReferenceIterator {
	return &ReferenceIterator{
		ptr:  ptr,
		repo: r,
	}
}

// Free the reference iterator
func (v *ReferenceIterator) Free() {
	runtime.SetFinalizer(v, nil)
	C.git_reference_iterator_free(v.ptr)
}

// ReferenceIsValidName ensures the reference name is well-formed.
//
// Valid reference names must follow one of two patterns:
//
// 1. Top-level names must contain only capital letters and underscores,
// and must begin and end with a letter. (e.g. "HEAD", "ORIG_HEAD").
//
// 2. Names prefixed with "refs/" can be almost anything. You must avoid
// the characters '~', '^', ':', ' \ ', '?', '[', and '*', and the sequences
// ".." and " @ {" which have special meaning to revparse.
func ReferenceIsValidName(name string) bool {
	cname := C.CString(name)
	defer C.free(unsafe.Pointer(cname))
	if C.git_reference_is_valid_name(cname) == 1 {
		return true
	}
	return false
}
