package git

/*
#include <git2.h>
*/
import "C"

import (
	"runtime"
	"unsafe"
)

type Status int

const (
	StatusCurrent         Status = C.GIT_STATUS_CURRENT
	StatusIndexNew        Status = C.GIT_STATUS_INDEX_NEW
	StatusIndexModified   Status = C.GIT_STATUS_INDEX_MODIFIED
	StatusIndexDeleted    Status = C.GIT_STATUS_INDEX_DELETED
	StatusIndexRenamed    Status = C.GIT_STATUS_INDEX_RENAMED
	StatusIndexTypeChange Status = C.GIT_STATUS_INDEX_TYPECHANGE
	StatusWtNew           Status = C.GIT_STATUS_WT_NEW
	StatusWtModified      Status = C.GIT_STATUS_WT_MODIFIED
	StatusWtDeleted       Status = C.GIT_STATUS_WT_DELETED
	StatusWtTypeChange    Status = C.GIT_STATUS_WT_TYPECHANGE
	StatusWtRenamed       Status = C.GIT_STATUS_WT_RENAMED
	StatusIgnored         Status = C.GIT_STATUS_IGNORED
	StatusConflicted      Status = C.GIT_STATUS_CONFLICTED
)

type StatusEntry struct {
	Status         Status
	HeadToIndex    DiffDelta
	IndexToWorkdir DiffDelta
}

func statusEntryFromC(statusEntry *C.git_status_entry) StatusEntry {
	var headToIndex DiffDelta = DiffDelta{}
	var indexToWorkdir DiffDelta = DiffDelta{}

	// Based on the libgit2 status example, head_to_index can be null in some cases
	if statusEntry.head_to_index != nil {
		headToIndex = diffDeltaFromC(statusEntry.head_to_index)
	}
	if statusEntry.index_to_workdir != nil {
		indexToWorkdir = diffDeltaFromC(statusEntry.index_to_workdir)
	}

	return StatusEntry{
		Status:         Status(statusEntry.status),
		HeadToIndex:    headToIndex,
		IndexToWorkdir: indexToWorkdir,
	}
}

type StatusList struct {
	ptr *C.git_status_list
	r   *Repository
}

func newStatusListFromC(ptr *C.git_status_list, r *Repository) *StatusList {
	if ptr == nil {
		return nil
	}

	statusList := &StatusList{
		ptr: ptr,
		r:   r,
	}

	runtime.SetFinalizer(statusList, (*StatusList).Free)
	return statusList
}

func (statusList *StatusList) Free() {
	if statusList.ptr == nil {
		return
	}
	runtime.SetFinalizer(statusList, nil)
	C.git_status_list_free(statusList.ptr)
	statusList.ptr = nil
}

func (statusList *StatusList) ByIndex(index int) (StatusEntry, error) {
	if statusList.ptr == nil {
		return StatusEntry{}, ErrInvalid
	}
	ptr := C.git_status_byindex(statusList.ptr, C.size_t(index))
	entry := statusEntryFromC(ptr)
	runtime.KeepAlive(statusList)

	return entry, nil
}

func (statusList *StatusList) EntryCount() (int, error) {
	if statusList.ptr == nil {
		return -1, ErrInvalid
	}
	ret := int(C.git_status_list_entrycount(statusList.ptr))
	runtime.KeepAlive(statusList)

	return ret, nil
}

type StatusOpt int

const (
	StatusOptIncludeUntracked      StatusOpt = C.GIT_STATUS_OPT_INCLUDE_UNTRACKED
	StatusOptIncludeIgnored        StatusOpt = C.GIT_STATUS_OPT_INCLUDE_IGNORED
	StatusOptIncludeUnmodified     StatusOpt = C.GIT_STATUS_OPT_INCLUDE_UNMODIFIED
	StatusOptExcludeSubmodules     StatusOpt = C.GIT_STATUS_OPT_EXCLUDE_SUBMODULES
	StatusOptRecurseUntrackedDirs  StatusOpt = C.GIT_STATUS_OPT_RECURSE_UNTRACKED_DIRS
	StatusOptDisablePathspecMatch  StatusOpt = C.GIT_STATUS_OPT_DISABLE_PATHSPEC_MATCH
	StatusOptRecurseIgnoredDirs    StatusOpt = C.GIT_STATUS_OPT_RECURSE_IGNORED_DIRS
	StatusOptRenamesHeadToIndex    StatusOpt = C.GIT_STATUS_OPT_RENAMES_HEAD_TO_INDEX
	StatusOptRenamesIndexToWorkdir StatusOpt = C.GIT_STATUS_OPT_RENAMES_INDEX_TO_WORKDIR
	StatusOptSortCaseSensitively   StatusOpt = C.GIT_STATUS_OPT_SORT_CASE_SENSITIVELY
	StatusOptSortCaseInsensitively StatusOpt = C.GIT_STATUS_OPT_SORT_CASE_INSENSITIVELY
	StatusOptRenamesFromRewrites   StatusOpt = C.GIT_STATUS_OPT_RENAMES_FROM_REWRITES
	StatusOptNoRefresh             StatusOpt = C.GIT_STATUS_OPT_NO_REFRESH
	StatusOptUpdateIndex           StatusOpt = C.GIT_STATUS_OPT_UPDATE_INDEX
)

type StatusShow int

const (
	StatusShowIndexAndWorkdir StatusShow = C.GIT_STATUS_SHOW_INDEX_AND_WORKDIR
	StatusShowIndexOnly       StatusShow = C.GIT_STATUS_SHOW_INDEX_ONLY
	StatusShowWorkdirOnly     StatusShow = C.GIT_STATUS_SHOW_WORKDIR_ONLY
)

type StatusOptions struct {
	Show     StatusShow
	Flags    StatusOpt
	Pathspec []string
}

func (v *Repository) StatusList(opts *StatusOptions) (*StatusList, error) {
	var ptr *C.git_status_list
	var copts *C.git_status_options

	if opts != nil {
		cpathspec := C.git_strarray{}
		if opts.Pathspec != nil {
			cpathspec.count = C.size_t(len(opts.Pathspec))
			cpathspec.strings = makeCStringsFromStrings(opts.Pathspec)
			defer freeStrarray(&cpathspec)
		}

		copts = &C.git_status_options{
			version:  C.GIT_STATUS_OPTIONS_VERSION,
			show:     C.git_status_show_t(opts.Show),
			flags:    C.uint(opts.Flags),
			pathspec: cpathspec,
		}
	} else {
		copts = &C.git_status_options{}
		ret := C.git_status_init_options(copts, C.GIT_STATUS_OPTIONS_VERSION)
		if ret < 0 {
			return nil, MakeGitError(ret)
		}
	}

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_status_list_new(&ptr, v.ptr, copts)
	if ret < 0 {
		return nil, MakeGitError(ret)
	}

	return newStatusListFromC(ptr, v), nil
}

func (v *Repository) StatusFile(path string) (Status, error) {
	var statusFlags C.uint
	cPath := C.CString(path)
	defer C.free(unsafe.Pointer(cPath))

	runtime.LockOSThread()
	defer runtime.UnlockOSThread()

	ret := C.git_status_file(&statusFlags, v.ptr, cPath)
	runtime.KeepAlive(v)
	if ret < 0 {
		return 0, MakeGitError(ret)
	}
	return Status(statusFlags), nil
}
