package git

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

type ErrorClass int

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

type ErrorCode int

const (

	// No error
	ErrOk ErrorCode = C.GIT_OK
	// Generic error
	ErrGeneric = C.GIT_ERROR
	// Requested object could not be found
	ErrNotFound = C.GIT_ENOTFOUND
	// Object exists preventing operation
	ErrExists = C.GIT_EEXISTS
	// More than one object matches
	ErrAmbigious = C.GIT_EAMBIGUOUS
	// Output buffer too short to hold data
	ErrBuffs = 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 = C.GIT_EUSER
	// Operation not allowed on bare repository
	ErrBareRepo = C.GIT_EBAREREPO
	// HEAD refers to branch with no commits
	ErrUnbornBranch = C.GIT_EUNBORNBRANCH
	// Merge in progress prevented operation
	ErrUnmerged = C.GIT_EUNMERGED
	// Reference was not fast-forwardable
	ErrNonFastForward = C.GIT_ENONFASTFORWARD
	// Name/ref spec was not in a valid format
	ErrInvalidSpec = C.GIT_EINVALIDSPEC
	// Merge conflicts prevented operation
	ErrMergeConflict = C.GIT_EMERGECONFLICT
	// Lock file prevented operation
	ErrLocked = C.GIT_ELOCKED
	// Reference value does not match expected
	ErrModified = C.GIT_EMODIFIED
	// Internal only
	ErrPassthrough = C.GIT_PASSTHROUGH
	// Signals end of iteration with iterator
	ErrIterOver = C.GIT_ITEROVER
)

var (
	ErrInvalid = errors.New("Invalid state for operation")
	ErrPushUnpack = errors.New("Error unpacking on the remote end")
)

func init() {
	C.git_threads_init()
}

// 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 != ErrIterOver {
		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
}
