package git

/*
#include <git2.h>
#include <git2/sys/openssl.h>
#cgo pkg-config: libgit2
*/
import "C"
import (
	"bytes"
	"encoding/hex"
	"errors"
	"runtime"
	"strings"
	"unsafe"
)

type ErrorClass int

const (
	ErrClassNone       ErrorClass = C.GITERR_NONE
	ErrClassNoMemory   ErrorClass = C.GITERR_NOMEMORY
	ErrClassOs         ErrorClass = C.GITERR_OS
	ErrClassInvalid    ErrorClass = C.GITERR_INVALID
	ErrClassReference  ErrorClass = C.GITERR_REFERENCE
	ErrClassZlib       ErrorClass = C.GITERR_ZLIB
	ErrClassRepository ErrorClass = C.GITERR_REPOSITORY
	ErrClassConfig     ErrorClass = C.GITERR_CONFIG
	ErrClassRegex      ErrorClass = C.GITERR_REGEX
	ErrClassOdb        ErrorClass = C.GITERR_ODB
	ErrClassIndex      ErrorClass = C.GITERR_INDEX
	ErrClassObject     ErrorClass = C.GITERR_OBJECT
	ErrClassNet        ErrorClass = C.GITERR_NET
	ErrClassTag        ErrorClass = C.GITERR_TAG
	ErrClassTree       ErrorClass = C.GITERR_TREE
	ErrClassIndexer    ErrorClass = C.GITERR_INDEXER
	ErrClassSSL        ErrorClass = C.GITERR_SSL
	ErrClassSubmodule  ErrorClass = C.GITERR_SUBMODULE
	ErrClassThread     ErrorClass = C.GITERR_THREAD
	ErrClassStash      ErrorClass = C.GITERR_STASH
	ErrClassCheckout   ErrorClass = C.GITERR_CHECKOUT
	ErrClassFetchHead  ErrorClass = C.GITERR_FETCHHEAD
	ErrClassMerge      ErrorClass = C.GITERR_MERGE
	ErrClassSsh        ErrorClass = C.GITERR_SSH
	ErrClassFilter     ErrorClass = C.GITERR_FILTER
	ErrClassRevert     ErrorClass = C.GITERR_REVERT
	ErrClassCallback   ErrorClass = C.GITERR_CALLBACK
)

type ErrorCode int

const (

	// No error
	ErrOk ErrorCode = C.GIT_OK
	// Generic error
	ErrGeneric ErrorCode = C.GIT_ERROR
	// Requested object could not be found
	ErrNotFound ErrorCode = C.GIT_ENOTFOUND
	// Object exists preventing operation
	ErrExists ErrorCode = C.GIT_EEXISTS
	// More than one object matches
	ErrAmbigious ErrorCode = C.GIT_EAMBIGUOUS
	// Output buffer too short to hold data
	ErrBuffs ErrorCode = C.GIT_EBUFS
	// GIT_EUSER is a special error that is never generated by libgit2
	// code.  You can return it from a callback (e.g to stop an iteration)
	// to know that it was generated by the callback and not by libgit2.
	ErrUser ErrorCode = C.GIT_EUSER
	// Operation not allowed on bare repository
	ErrBareRepo ErrorCode = C.GIT_EBAREREPO
	// HEAD refers to branch with no commits
	ErrUnbornBranch ErrorCode = C.GIT_EUNBORNBRANCH
	// Merge in progress prevented operation
	ErrUnmerged ErrorCode = C.GIT_EUNMERGED
	// Reference was not fast-forwardable
	ErrNonFastForward ErrorCode = C.GIT_ENONFASTFORWARD
	// Name/ref spec was not in a valid format
	ErrInvalidSpec ErrorCode = C.GIT_EINVALIDSPEC
	// Merge conflicts prevented operation
	ErrMergeConflict ErrorCode = C.GIT_EMERGECONFLICT
	// Lock file prevented operation
	ErrLocked ErrorCode = C.GIT_ELOCKED
	// Reference value does not match expected
	ErrModified ErrorCode = C.GIT_EMODIFIED
	// Internal only
	ErrPassthrough ErrorCode = C.GIT_PASSTHROUGH
	// Signals end of iteration with iterator
	ErrIterOver ErrorCode = C.GIT_ITEROVER
	// Authentication failed
	ErrAuth ErrorCode = C.GIT_EAUTH
)

var (
	ErrInvalid = errors.New("Invalid state for operation")
)

var pointerHandles *HandleList

func init() {
	pointerHandles = NewHandleList()

	C.git_libgit2_init()

	// This is not something we should be doing, as we may be
	// stomping all over someone else's setup. The user should do
	// this themselves or use some binding/wrapper which does it
	// in such a way that they can be sure they're the only ones
	// setting it up.
	C.git_openssl_set_locking()
}

// Oid represents the id for a Git object.
type Oid [20]byte

func newOidFromC(coid *C.git_oid) *Oid {
	if coid == nil {
		return nil
	}

	oid := new(Oid)
	copy(oid[0:20], C.GoBytes(unsafe.Pointer(coid), 20))
	return oid
}

func NewOidFromBytes(b []byte) *Oid {
	oid := new(Oid)
	copy(oid[0:20], b[0:20])
	return oid
}

func (oid *Oid) toC() *C.git_oid {
	return (*C.git_oid)(unsafe.Pointer(oid))
}

func NewOid(s string) (*Oid, error) {
	if len(s) > C.GIT_OID_HEXSZ {
		return nil, errors.New("string is too long for oid")
	}

	o := new(Oid)

	slice, error := hex.DecodeString(s)
	if error != nil {
		return nil, error
	}

	if len(slice) != 20 {
		return nil, &GitError{"Invalid Oid", ErrClassNone, ErrGeneric}
	}

	copy(o[:], slice[:20])
	return o, nil
}

func (oid *Oid) String() string {
	return hex.EncodeToString(oid[:])
}

func (oid *Oid) Cmp(oid2 *Oid) int {
	return bytes.Compare(oid[:], oid2[:])
}

func (oid *Oid) Copy() *Oid {
	ret := new(Oid)
	copy(ret[:], oid[:])
	return ret
}

func (oid *Oid) Equal(oid2 *Oid) bool {
	return bytes.Equal(oid[:], oid2[:])
}

func (oid *Oid) IsZero() bool {
	for _, a := range oid {
		if a != 0 {
			return false
		}
	}
	return true
}

func (oid *Oid) NCmp(oid2 *Oid, n uint) int {
	return bytes.Compare(oid[:n], oid2[:n])
}

func ShortenOids(ids []*Oid, minlen int) (int, error) {
	shorten := C.git_oid_shorten_new(C.size_t(minlen))
	if shorten == nil {
		panic("Out of memory")
	}
	defer C.git_oid_shorten_free(shorten)

	var ret C.int

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	for _, id := range ids {
		buf := make([]byte, 41)
		C.git_oid_fmt((*C.char)(unsafe.Pointer(&buf[0])), id.toC())
		buf[40] = 0
		ret = C.git_oid_shorten_add(shorten, (*C.char)(unsafe.Pointer(&buf[0])))
		if ret < 0 {
			return int(ret), MakeGitError(ret)
		}
	}
	return int(ret), nil
}

type GitError struct {
	Message string
	Class   ErrorClass
	Code    ErrorCode
}

func (e GitError) Error() string {
	return e.Message
}

func IsErrorClass(err error, c ErrorClass) bool {

	if err == nil {
		return false
	}
	if gitError, ok := err.(*GitError); ok {
		return gitError.Class == c
	}
	return false
}

func IsErrorCode(err error, c ErrorCode) bool {
	if err == nil {
		return false
	}
	if gitError, ok := err.(*GitError); ok {
		return gitError.Code == c
	}
	return false
}

func MakeGitError(errorCode C.int) error {

	var errMessage string
	var errClass ErrorClass
	if errorCode != C.GIT_ITEROVER {
		err := C.giterr_last()
		if err != nil {
			errMessage = C.GoString(err.message)
			errClass = ErrorClass(err.klass)
		} else {
			errClass = ErrClassInvalid
		}
	}
	return &GitError{errMessage, errClass, ErrorCode(errorCode)}
}

func MakeGitError2(err int) error {
	return MakeGitError(C.int(err))
}

func cbool(b bool) C.int {
	if b {
		return C.int(1)
	}
	return C.int(0)
}

func ucbool(b bool) C.uint {
	if b {
		return C.uint(1)
	}
	return C.uint(0)
}

func Discover(start string, across_fs bool, ceiling_dirs []string) (string, error) {
	ceildirs := C.CString(strings.Join(ceiling_dirs, string(C.GIT_PATH_LIST_SEPARATOR)))
	defer C.free(unsafe.Pointer(ceildirs))

	cstart := C.CString(start)
	defer C.free(unsafe.Pointer(cstart))

	var buf C.git_buf
	defer C.git_buf_free(&buf)

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_repository_discover(&buf, cstart, cbool(across_fs), ceildirs)
	if ret < 0 {
		return "", MakeGitError(ret)
	}

	return C.GoString(buf.ptr), nil
}
