package git

/*
#include <git2.h>
#include <git2/sys/openssl.h>
*/
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
)

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

func init() {
	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
}
