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.uint32_t(opts.MinLine),
			max_line:             C.uint32_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)
	if ecode < 0 {
		return nil, MakeGitError(ecode)
	}

	return newBlameFromC(blamePtr), nil
}

type Blame struct {
	ptr *C.git_blame
}

func (blame *Blame) HunkCount() int {
	return int(C.git_blame_get_hunk_count(blame.ptr))
}

func (blame *Blame) HunkByIndex(index int) (BlameHunk, error) {
	ptr := C.git_blame_get_hunk_byindex(blame.ptr, C.uint32_t(index))
	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.uint32_t(lineno))
	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,
	}
}
