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
)

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
}

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

	statusList := &StatusList{
		ptr: ptr,
	}

	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))
	return statusEntryFromC(ptr), nil
}

func (statusList *StatusList) EntryCount() (int, error) {
	if statusList.ptr == nil {
		return -1, ErrInvalid
	}
	return int(C.git_status_list_entrycount(statusList.ptr)), 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), 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)
	if ret < 0 {
		return 0, MakeGitError(ret)
	}
	return Status(statusFlags), nil
}
