package git

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

type BlameOptions struct {
	Flags              BlameOptionsFlag
	MinMatchCharacters uint16
	NewestCommit       *Oid
	OldestCommit       *Oid
	MinLine            uint32
	MaxLine            uint32
}

func DefaultBlameOptions() (BlameOptions, error) {
	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	opts := C.git_blame_options{}
	ecode := C.git_blame_init_options(&opts, C.GIT_BLAME_OPTIONS_VERSION)
	if ecode < 0 {
		return BlameOptions{}, MakeGitError(ecode)
	}

	return BlameOptions{
		Flags:              BlameOptionsFlag(opts.flags),
		MinMatchCharacters: uint16(opts.min_match_characters),
		NewestCommit:       newOidFromC(&opts.newest_commit),
		OldestCommit:       newOidFromC(&opts.oldest_commit),
		MinLine:            uint32(opts.min_line),
		MaxLine:            uint32(opts.max_line),
	}, nil
}

type BlameOptionsFlag uint32

const (
	BlameNormal                      BlameOptionsFlag = C.GIT_BLAME_NORMAL
	BlameTrackCopiesSameFile         BlameOptionsFlag = C.GIT_BLAME_TRACK_COPIES_SAME_FILE
	BlameTrackCopiesSameCommitMoves  BlameOptionsFlag = C.GIT_BLAME_TRACK_COPIES_SAME_COMMIT_MOVES
	BlameTrackCopiesSameCommitCopies BlameOptionsFlag = C.GIT_BLAME_TRACK_COPIES_SAME_COMMIT_COPIES
	BlameTrackCopiesAnyCommitCopies  BlameOptionsFlag = C.GIT_BLAME_TRACK_COPIES_ANY_COMMIT_COPIES
	BlameFirstParent                 BlameOptionsFlag = C.GIT_BLAME_FIRST_PARENT
)

func (v *Repository) BlameFile(path string, opts *BlameOptions) (*Blame, error) {
	var blamePtr *C.git_blame

	var copts *C.git_blame_options
	if opts != nil {
		copts = &C.git_blame_options{
			version:              C.GIT_BLAME_OPTIONS_VERSION,
			flags:                C.uint32_t(opts.Flags),
			min_match_characters: C.uint16_t(opts.MinMatchCharacters),
			min_line:             C.size_t(opts.MinLine),
			max_line:             C.size_t(opts.MaxLine),
		}
		if opts.NewestCommit != nil {
			copts.newest_commit = *opts.NewestCommit.toC()
		}
		if opts.OldestCommit != nil {
			copts.oldest_commit = *opts.OldestCommit.toC()
		}
	}

	cpath := C.CString(path)
	defer C.free(unsafe.Pointer(cpath))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ecode := C.git_blame_file(&blamePtr, v.ptr, cpath, copts)
	runtime.KeepAlive(v)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return newBlameFromC(blamePtr), nil
}

type Blame struct {
	ptr *C.git_blame
}

func (blame *Blame) HunkCount() int {
	ret := int(C.git_blame_get_hunk_count(blame.ptr))
	runtime.KeepAlive(blame)

	return ret
}

func (blame *Blame) HunkByIndex(index int) (BlameHunk, error) {
	ptr := C.git_blame_get_hunk_byindex(blame.ptr, C.uint32_t(index))
	runtime.KeepAlive(blame)
	if ptr == nil {
		return BlameHunk{}, ErrInvalid
	}
	return blameHunkFromC(ptr), nil
}

func (blame *Blame) HunkByLine(lineno int) (BlameHunk, error) {
	ptr := C.git_blame_get_hunk_byline(blame.ptr, C.size_t(lineno))
	runtime.KeepAlive(blame)
	if ptr == nil {
		return BlameHunk{}, ErrInvalid
	}
	return blameHunkFromC(ptr), nil
}

func newBlameFromC(ptr *C.git_blame) *Blame {
	if ptr == nil {
		return nil
	}

	blame := &Blame{
		ptr: ptr,
	}

	runtime.SetFinalizer(blame, (*Blame).Free)
	return blame
}

func (blame *Blame) Free() error {
	if blame.ptr == nil {
		return ErrInvalid
	}
	runtime.SetFinalizer(blame, nil)
	C.git_blame_free(blame.ptr)
	blame.ptr = nil
	return nil
}

type BlameHunk struct {
	LinesInHunk          uint16
	FinalCommitId        *Oid
	FinalStartLineNumber uint16
	FinalSignature       *Signature
	OrigCommitId         *Oid
	OrigPath             string
	OrigStartLineNumber  uint16
	OrigSignature        *Signature
	Boundary             bool
}

func blameHunkFromC(hunk *C.git_blame_hunk) BlameHunk {
	return BlameHunk{
		LinesInHunk:          uint16(hunk.lines_in_hunk),
		FinalCommitId:        newOidFromC(&hunk.final_commit_id),
		FinalStartLineNumber: uint16(hunk.final_start_line_number),
		FinalSignature:       newSignatureFromC(hunk.final_signature),
		OrigCommitId:         newOidFromC(&hunk.orig_commit_id),
		OrigPath:             C.GoString(hunk.orig_path),
		OrigStartLineNumber:  uint16(hunk.orig_start_line_number),
		OrigSignature:        newSignatureFromC(hunk.orig_signature),
		Boundary:             hunk.boundary == 1,
	}
}
