#include "git-compat-util.h"
#include "config.h"
#include "fsmonitor-ll.h"
#include "fsm-health.h"
#include "fsmonitor--daemon.h"
#include "gettext.h"
#include "simple-ipc.h"

/*
 * Every minute wake up and test our health.
 */
#define WAIT_FREQ_MS (60 * 1000)

/*
 * State machine states for each of the interval functions
 * used for polling our health.
 */
enum interval_fn_ctx {
	CTX_INIT = 0,
	CTX_TERM,
	CTX_TIMER
};

typedef int (interval_fn)(struct fsmonitor_daemon_state *state,
			  enum interval_fn_ctx ctx);

struct fsm_health_data
{
	HANDLE hEventShutdown;

	HANDLE hHandles[1]; /* the array does not own these handles */
#define HEALTH_SHUTDOWN 0
	int nr_handles; /* number of active event handles */

	struct wt_moved
	{
		wchar_t wpath[MAX_PATH + 1];
		BY_HANDLE_FILE_INFORMATION bhfi;
	} wt_moved;
};

/*
 * Lookup the system unique ID for the path.  This is as close as
 * we get to an inode number, but this also contains volume info,
 * so it is a little stronger.
 */
static int lookup_bhfi(wchar_t *wpath,
		       BY_HANDLE_FILE_INFORMATION *bhfi)
{
	DWORD desired_access = FILE_LIST_DIRECTORY;
	DWORD share_mode =
		FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE;
	HANDLE hDir;

	hDir = CreateFileW(wpath, desired_access, share_mode, NULL,
			   OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
	if (hDir == INVALID_HANDLE_VALUE) {
		error(_("[GLE %ld] health thread could not open '%ls'"),
		      GetLastError(), wpath);
		return -1;
	}

	if (!GetFileInformationByHandle(hDir, bhfi)) {
		error(_("[GLE %ld] health thread getting BHFI for '%ls'"),
		      GetLastError(), wpath);
		CloseHandle(hDir);
		return -1;
	}

	CloseHandle(hDir);
	return 0;
}

/*
 * Compare the relevant fields from two system unique IDs.
 * We use this to see if two different handles to the same
 * path actually refer to the same *instance* of the file
 * or directory.
 */
static int bhfi_eq(const BY_HANDLE_FILE_INFORMATION *bhfi_1,
		   const BY_HANDLE_FILE_INFORMATION *bhfi_2)
{
	return (bhfi_1->dwVolumeSerialNumber == bhfi_2->dwVolumeSerialNumber &&
		bhfi_1->nFileIndexHigh == bhfi_2->nFileIndexHigh &&
		bhfi_1->nFileIndexLow == bhfi_2->nFileIndexLow);
}

/*
 * Shutdown if the original worktree root directory been deleted,
 * moved, or renamed?
 *
 * Since the main thread did a "chdir(getenv($HOME))" and our CWD
 * is not in the worktree root directory and because the listener
 * thread added FILE_SHARE_DELETE to the watch handle, it is possible
 * for the root directory to be moved or deleted while we are still
 * watching it.  We want to detect that here and force a shutdown.
 *
 * Granted, a delete MAY cause some operations to fail, such as
 * GetOverlappedResult(), but it is not guaranteed.  And because
 * ReadDirectoryChangesW() only reports on changes *WITHIN* the
 * directory, not changes *ON* the directory, our watch will not
 * receive a delete event for it.
 *
 * A move/rename of the worktree root will also not generate an event.
 * And since the listener thread already has an open handle, it may
 * continue to receive events for events within the directory.
 * However, the pathname of the named-pipe was constructed using the
 * original location of the worktree root.  (Remember named-pipes are
 * stored in the NPFS and not in the actual file system.)  Clients
 * trying to talk to the worktree after the move/rename will not
 * reach our daemon process, since we're still listening on the
 * pipe with original path.
 *
 * Furthermore, if the user does something like:
 *
 *   $ mv repo repo.old
 *   $ git init repo
 *
 * A new daemon cannot be started in the new instance of "repo"
 * because the named-pipe is still being used by the daemon on
 * the original instance.
 *
 * So, detect move/rename/delete and shutdown.  This should also
 * handle unsafe drive removal.
 *
 * We use the file system unique ID to distinguish the original
 * directory instance from a new instance and force a shutdown
 * if the unique ID changes.
 *
 * Since a worktree move/rename/delete/unmount doesn't happen
 * that often (and we can't get an immediate event anyway), we
 * use a timeout and periodically poll it.
 */
static int has_worktree_moved(struct fsmonitor_daemon_state *state,
			      enum interval_fn_ctx ctx)
{
	struct fsm_health_data *data = state->health_data;
	BY_HANDLE_FILE_INFORMATION bhfi;
	int r;

	switch (ctx) {
	case CTX_TERM:
		return 0;

	case CTX_INIT:
		if (xutftowcs_path(data->wt_moved.wpath,
				   state->path_worktree_watch.buf) < 0) {
			error(_("could not convert to wide characters: '%s'"),
			      state->path_worktree_watch.buf);
			return -1;
		}

		/*
		 * On the first call we lookup the unique sequence ID for
		 * the worktree root directory.
		 */
		return lookup_bhfi(data->wt_moved.wpath, &data->wt_moved.bhfi);

	case CTX_TIMER:
		r = lookup_bhfi(data->wt_moved.wpath, &bhfi);
		if (r)
			return r;
		if (!bhfi_eq(&data->wt_moved.bhfi, &bhfi)) {
			error(_("BHFI changed '%ls'"), data->wt_moved.wpath);
			return -1;
		}
		return 0;

	default:
		die(_("unhandled case in 'has_worktree_moved': %d"),
		    (int)ctx);
	}

	return 0;
}


int fsm_health__ctor(struct fsmonitor_daemon_state *state)
{
	struct fsm_health_data *data;

	CALLOC_ARRAY(data, 1);

	data->hEventShutdown = CreateEvent(NULL, TRUE, FALSE, NULL);

	data->hHandles[HEALTH_SHUTDOWN] = data->hEventShutdown;
	data->nr_handles++;

	state->health_data = data;
	return 0;
}

void fsm_health__dtor(struct fsmonitor_daemon_state *state)
{
	struct fsm_health_data *data;

	if (!state || !state->health_data)
		return;

	data = state->health_data;

	CloseHandle(data->hEventShutdown);

	FREE_AND_NULL(state->health_data);
}

/*
 * A table of the polling functions.
 */
static interval_fn *table[] = {
	has_worktree_moved,
	NULL, /* must be last */
};

/*
 * Call all of the polling functions in the table.
 * Shortcut and return first error.
 *
 * Return 0 if all succeeded.
 */
static int call_all(struct fsmonitor_daemon_state *state,
		    enum interval_fn_ctx ctx)
{
	int k;

	for (k = 0; table[k]; k++) {
		int r = table[k](state, ctx);
		if (r)
			return r;
	}

	return 0;
}

void fsm_health__loop(struct fsmonitor_daemon_state *state)
{
	struct fsm_health_data *data = state->health_data;
	int r;

	r = call_all(state, CTX_INIT);
	if (r < 0)
		goto force_error_stop;
	if (r > 0)
		goto force_shutdown;

	for (;;) {
		DWORD dwWait = WaitForMultipleObjects(data->nr_handles,
						      data->hHandles,
						      FALSE, WAIT_FREQ_MS);

		if (dwWait == WAIT_OBJECT_0 + HEALTH_SHUTDOWN)
			goto clean_shutdown;

		if (dwWait == WAIT_TIMEOUT) {
			r = call_all(state, CTX_TIMER);
			if (r < 0)
				goto force_error_stop;
			if (r > 0)
				goto force_shutdown;
			continue;
		}

		error(_("health thread wait failed [GLE %ld]"),
		      GetLastError());
		goto force_error_stop;
	}

force_error_stop:
	state->health_error_code = -1;
force_shutdown:
	ipc_server_stop_async(state->ipc_server_data);
clean_shutdown:
	call_all(state, CTX_TERM);
	return;
}

void fsm_health__stop_async(struct fsmonitor_daemon_state *state)
{
	SetEvent(state->health_data->hHandles[HEALTH_SHUTDOWN]);
}
