/*
 * Copyright (C) the libgit2 contributors. All rights reserved.
 *
 * This file is part of libgit2, distributed under the GNU GPL v2 with
 * a Linking Exception. For full terms see the included COPYING file.
 */

#if defined(GIT_MSVC_CRTDBG)
#include "Windows.h"
#include "Dbghelp.h"
#include "win32/posix.h"
#include "w32_stack.h"
#include "hash.h"

/**
 * This is supposedly defined in WinBase.h (from Windows.h) but there were linker issues.
 */
USHORT WINAPI RtlCaptureStackBackTrace(ULONG, ULONG, PVOID*, PULONG);

static bool   g_win32_stack_initialized = false;
static HANDLE g_win32_stack_process = INVALID_HANDLE_VALUE;
static git_win32__stack__aux_cb_alloc  g_aux_cb_alloc  = NULL;
static git_win32__stack__aux_cb_lookup g_aux_cb_lookup = NULL;

int git_win32__stack__set_aux_cb(
	git_win32__stack__aux_cb_alloc cb_alloc,
	git_win32__stack__aux_cb_lookup cb_lookup)
{
	g_aux_cb_alloc = cb_alloc;
	g_aux_cb_lookup = cb_lookup;

	return 0;
}

void git_win32__stack_init(void)
{
	if (!g_win32_stack_initialized) {
		g_win32_stack_process = GetCurrentProcess();
		SymSetOptions(SYMOPT_LOAD_LINES);
		SymInitialize(g_win32_stack_process, NULL, TRUE);
		g_win32_stack_initialized = true;
	}
}

void git_win32__stack_cleanup(void)
{
	if (g_win32_stack_initialized) {
		SymCleanup(g_win32_stack_process);
		g_win32_stack_process = INVALID_HANDLE_VALUE;
		g_win32_stack_initialized = false;
	}
}

int git_win32__stack_capture(git_win32__stack__raw_data *pdata, int skip)
{
	if (!g_win32_stack_initialized) {
		giterr_set(GITERR_INVALID, "git_win32_stack not initialized.");
		return GIT_ERROR;
	}

	memset(pdata, 0, sizeof(*pdata));
	pdata->nr_frames = RtlCaptureStackBackTrace(
		skip+1, GIT_WIN32__STACK__MAX_FRAMES, pdata->frames, NULL);

	/* If an "aux" data provider was registered, ask it to capture
	 * whatever data it needs and give us an "aux_id" to it so that
	 * we can refer to it later when reporting.
	 */
	if (g_aux_cb_alloc)
		(g_aux_cb_alloc)(&pdata->aux_id);

	return 0;
}

int git_win32__stack_compare(
	git_win32__stack__raw_data *d1,
	git_win32__stack__raw_data *d2)
{
	return memcmp(d1, d2, sizeof(*d1));
}

int git_win32__stack_format(
	char *pbuf, int buf_len,
	const git_win32__stack__raw_data *pdata,
	const char *prefix, const char *suffix)
{
#define MY_MAX_FILENAME 255

	/* SYMBOL_INFO has char FileName[1] at the end.  The docs say to
	 * to malloc it with extra space for your desired max filename.
	 */
	struct {
		SYMBOL_INFO symbol;
		char extra[MY_MAX_FILENAME + 1];
	} s;

	IMAGEHLP_LINE64 line;
	int buf_used = 0;
	unsigned int k;
	char detail[MY_MAX_FILENAME * 2]; /* filename plus space for function name and formatting */
	int detail_len;

	if (!g_win32_stack_initialized) {
		giterr_set(GITERR_INVALID, "git_win32_stack not initialized.");
		return GIT_ERROR;
	}

	if (!prefix)
		prefix = "\t";
	if (!suffix)
		suffix = "\n";

	memset(pbuf, 0, buf_len);

	memset(&s, 0, sizeof(s));
	s.symbol.MaxNameLen = MY_MAX_FILENAME;
	s.symbol.SizeOfStruct = sizeof(SYMBOL_INFO);

	memset(&line, 0, sizeof(line));
	line.SizeOfStruct = sizeof(IMAGEHLP_LINE64);

	for (k=0; k < pdata->nr_frames; k++) {
		DWORD64 frame_k = (DWORD64)pdata->frames[k];
		DWORD dwUnused;

		if (SymFromAddr(g_win32_stack_process, frame_k, 0, &s.symbol) &&
			SymGetLineFromAddr64(g_win32_stack_process, frame_k, &dwUnused, &line)) {
			const char *pslash;
			const char *pfile;

			pslash = strrchr(line.FileName, '\\');
			pfile = ((pslash) ? (pslash+1) : line.FileName);
			p_snprintf(detail, sizeof(detail), "%s%s:%d> %s%s",
					   prefix, pfile, line.LineNumber, s.symbol.Name, suffix);
		} else {
			/* This happens when we cross into another module.
			 * For example, in CLAR tests, this is typically
			 * the CRT startup code.  Just print an unknown
			 * frame and continue.
			 */
			p_snprintf(detail, sizeof(detail), "%s??%s", prefix, suffix);
		}
		detail_len = strlen(detail);

		if (buf_len < (buf_used + detail_len + 1)) {
			/* we don't have room for this frame in the buffer, so just stop. */
			break;
		}

		memcpy(&pbuf[buf_used], detail, detail_len);
		buf_used += detail_len;
	}

	/* "aux_id" 0 is reserved to mean no aux data. This is needed to handle
	 * allocs that occur before the aux callbacks were registered.
	 */
	if (pdata->aux_id > 0) {
		p_snprintf(detail, sizeof(detail), "%saux_id: %d%s",
				   prefix, pdata->aux_id, suffix);
		detail_len = strlen(detail);
		if ((buf_used + detail_len + 1) < buf_len) {
			memcpy(&pbuf[buf_used], detail, detail_len);
			buf_used += detail_len;
		}

		/* If an "aux" data provider is still registered, ask it to append its detailed
		 * data to the end of ours using the "aux_id" it gave us when this de-duped
		 * item was created.
		 */
		if (g_aux_cb_lookup)
			(g_aux_cb_lookup)(pdata->aux_id, &pbuf[buf_used], (buf_len - buf_used - 1));
	}

	return GIT_OK;
}

int git_win32__stack(
	char * pbuf, int buf_len,
	int skip,
	const char *prefix, const char *suffix)
{
	git_win32__stack__raw_data data;
	int error;

	if ((error = git_win32__stack_capture(&data, skip)) < 0)
		return error;
	if ((error = git_win32__stack_format(pbuf, buf_len, &data, prefix, suffix)) < 0)
		return error;
	return 0;
}

#endif
