unit LLVM.Runner;

interface

uses
    System.SysUtils,
    Winapi.Windows,
    System.Classes;

type
    // Callback-Prozedur, die von der DLL aufgerufen wird
    TLogIntegerCallback = procedure(AValue: Integer); stdcall;

    // NEU: Typ für die Host-Additionsfunktion
    THostAddIntegersCallback = function(ANum1: Integer; ANum2: Integer): Integer; stdcall;

    // NEUE, VEREINFACHTE Signatur der exportierten DLL-Funktion
    // Jetzt nur noch der Log-Callback und der neue Integer-Input-Parameter
    TStarteLogikProc =
        procedure(
            ALogIntProc: TLogIntegerCallback;
            AHostInputInteger: Integer;
            AHostAddIntegersProc: THostAddIntegersCallback // <--- Der neue Host-Unterprogramm-Parameter
        ); stdcall;

type
    TLLVMRunner = class
    private
        FModule: HMODULE;
        FStarteLogik: TStarteLogikProc;
        class var
            FLog: TStrings;
        class procedure LogInteger(AValue: Integer); static; stdcall;
        // NEU: Host-Unterprogramm-Implementierung
        class function HostAddIntegers(ANum1: Integer; ANum2: Integer): Integer; static; stdcall;
    public
        constructor Create(const ADLLPath: string);
        destructor Destroy; override;
        procedure Execute(AInputInteger: Integer);
        class property Log: TStrings read FLog write FLog;
    end;

implementation

{ TLLVMRunner }

constructor TLLVMRunner.Create(const ADLLPath: string);
begin
    inherited Create;
    FModule := LoadLibrary(PChar(ADLLPath));
    if FModule = 0 then
        raise Exception.Create('Failed to load DLL.');

    FStarteLogik := GetProcAddress(FModule, 'StarteLogik');
    if not Assigned(FStarteLogik) then
        raise Exception.Create('Procedure "StarteLogik" not found in DLL.');
end;

destructor TLLVMRunner.Destroy;
begin
    if FModule <> 0 then
        FreeLibrary(FModule);
    inherited;
end;

// NEUE Implementierung der Host-Funktion
class function TLLVMRunner.HostAddIntegers(ANum1: Integer; ANum2: Integer): Integer;
begin
    Result := ANum1 + ANum2; // Die eigentliche Logik
    if Assigned(FLog) then
        FLog.Add(Format('DLL hat Host-Addition angefordert: %d + %d = %d', [ANum1, ANum2, Result]));
end;

// Die Execute-Methode muss angepasst werden, um den neuen Funktionszeiger zu übergeben
procedure TLLVMRunner.Execute(AInputInteger: Integer);
begin
    if Assigned(FStarteLogik) then
        FStarteLogik(
            LogInteger,
            AInputInteger,
            HostAddIntegers // <--- Adresse der Host-Funktion übergeben
        );
end;

// Dies ist die Methode, die die DLL für LogInteger aufruft.
class procedure TLLVMRunner.LogInteger(AValue: Integer);
begin
    if Assigned(FLog) then
        FLog.Add(Format('DLL logged integer: %d', [AValue]));
end;

// Die Implementierungen von GetCurrentDateTimeUTCHost und GetComponentInZoneHost
// wurden hier entfernt, da sie nicht mehr benötigt werden.

end.
