#Include %A_AppData%\..\..\Documents\AutoHotkey\Lib
#NoEnv  ; Recommended for performance and compatibility with future AutoHotkey releases.
; #Warn  ; Enable warnings to assist with detecting common errors.
SendMode Input  ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir%  ; Ensures a consistent starting directory.

class Logger {

	static Url := "<BASE_URL>plugin/com.suncode.plugin-rpa-manager/logs"
	static Cookie := "<JSESSIONID>"

	debug(content) {
		this.send(content, "DEBUG")
	}

	error(content) {
		this.send(content, "ERROR")
	}

	info(content) {
		this.send(content, "INFO")
	}

	trace(content) {
		this.send(content, "TRACE")
	}

	warn(content) {
		this.send(content, "WARN")
	}

	send(content, type) {
		Data = "{ "workerId": "<WORKER_ID>", "createdAt": 0, "content": "%content%", "type": "%type%" }"
		whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
		whr.Open("POST", This.Url, 0)
		whr.SetRequestHeader("Content-Type", "application/json")
		whr.SetRequestHeader("Cookie", This.Cookie)
		whr.Send(Data)
	}
}

class Comment {

	static Url := "<BASE_URL>plugin/com.suncode.plugin-rpa-manager/comments"
	static Cookie := "<JSESSIONID>"

	comment(content, activityId, processId) {
		this.send(content, activityId, processId)
	}

	send(content, activityId, processId) {
		Data = { "workerId": "<WORKER_ID>", "createdAt": 0, "content": "%content%", "processId": "%processId%", "activityId": "%activityId%" }
		whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
		whr.Open("POST", This.Url, 0)
		whr.SetRequestHeader("Content-Type", "application/json")
		whr.SetRequestHeader("Cookie", This.Cookie)
		whr.Send(Data)
	}
}

Screenshot(OutFile) {
	pToken := Gdip_Startup()
	screen = 0 | 0 | %A_ScreenWidth% | %A_ScreenHeight%
	pBitmap := Gdip_BitmapFromScreen(screen)

	Gdip_SaveBitmapToFile(pBitmap, OutFile, 100)
	Gdip_DisposeImage(pBitmap)
	Gdip_Shutdown(pToken)
}

Base64Enc(ByRef Bin, nBytes, LineLength := 64, LeadingSpaces := 0) {
	Local Rqd := 0, B64, B := "", N := 0 - LineLength + 1 ; CRYPT_STRING_BASE64 := 0x1
	DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &Bin, "UInt", nBytes, "UInt", 0x1, "Ptr", 0, "UIntP", Rqd)
	VarSetCapacity(B64, Rqd * ( A_Isunicode ? 2 : 1 ), 0)
	DllCall("Crypt32.dll\CryptBinaryToString", "Ptr", &Bin, "UInt", nBytes, "UInt", 0x1, "Str", B64, "UIntP", Rqd)
	If (LineLength = 64 and !LeadingSpaces)
		Return B64
	B64 := StrReplace(B64, "`r`n")
	Loop % Ceil(StrLen(B64) / LineLength)
		B .= Format("{1:" LeadingSpaces "s}", "") . SubStr(B64, N += LineLength, LineLength) . "`n"
	Return RTrim(B, "`n")
}

UrlEncode(String)
{
	OldFormat := A_FormatInteger
	SetFormat, Integer, H

	Loop, Parse, String
	{
		if A_LoopField is alnum
		{
			Out .= A_LoopField
			continue
		}
		Hex := SubStr( Asc( A_LoopField ), 3 )
		Out .= "%" . ( StrLen( Hex ) = 1 ? "0" . Hex : Hex )
	}

	SetFormat, Integer, %OldFormat%
	return Out
}

MakePrintScreenAndSend(activityId, processId)
{
	File := "<TEMPDIR_PATH>\PrintScreen.png"
	Screenshot(File)
	FileGetSize, nBytes, %File%
	FileRead, Bin, *c %File%
	B64Data := Base64Enc(Bin, nBytes, 1000000, 0)
	Files.uploadfile(UrlEncode(B64Data), activityId, processId, "<SCREENSHOT_DOCCLASSID>", "PrintScreen.png", "Ekran błędu")
}

class Files {

	static Url := "<BASE_URL>plugin/com.suncode.plugin-rpa-manager/uploadfile"
	static Cookie := "<JSESSIONID>"

	uploadfile(base64content, activityId, processId, docclassId, fileName, description) {
		Data = { "content": "%base64content%", "processId": "%processId%", "activityId": "%activityId%", "docclassId": "%docclassId%", "description": "%description%", "fileName": "%fileName%" }
		whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
		whr.Open("POST", This.Url, 0)
		whr.SetRequestHeader("Content-Type", "application/json")
		whr.SetRequestHeader("Cookie", This.Cookie)
		whr.Send(Data)
	}
}


try {

	@CONTEXT_MAP@

    scriptStartLine := A_LineNumber
	@SCRIPT_CONTENT@

} catch e {
    errorDescription := "Error Message: "
    if (IsObject(e)) {
        errorDescription .= e.message
        if (ObjHasKey(e, "line") && e.line != "") {
            relativeLineNumber := e.line - scriptStartLine
            errorDescription .= ", Line: " . relativeLineNumber
        }
        if (ObjHasKey(e, "what") && e.what != "") {
            errorDescription .= ", What: " . e.what
        }
        if (ObjHasKey(e, "extra") && e.extra != "") {
            errorDescription .= ", Extra: " . e.extra
        }
        if (ObjHasKey(e, "file") && e.file != "") {
            errorDescription .= "<br />File: " . e.file
            if (ObjHasKey(e, "line") && e.line != "") {
                errorDescription .= ":" . e.line
            }
        }
    }
    else if (e is string) {
        errorDescription .= e
    }
    errorDescription := StrReplace(errorDescription, "\", "\\\\")

	Logger.error("Worker '<WORKER_NAME>': Error occurred during execution of Script='<SCRIPT_ID>' for ProcessId='" . proccessId
	    . "' and ActivityId='" . activityId . "'.<br />" . errorDescription)

    if ("<SCREENSHOT_DOCCLASSID>" != "") {
	    MakePrintScreenAndSend(activityId, proccessId)
    }
	ExitApp -1
}