unit uWatchdog;

interface

uses
  System.Classes, System.SysUtils, System.IOUtils, uConfig, uProcessor, uDM,
  Winapi.Windows;

type
  TDirectoryWatchdog = class(TThread)
  private
    FStopEvent: THandle;
    procedure ScanDirectory;
  protected
    procedure Execute; override;
  public
    constructor Create;
    destructor Destroy; override;
    procedure SignalStop;
  end;

implementation

{ TDirectoryWatchdog }

constructor TDirectoryWatchdog.Create;
begin
  inherited Create(False);
  FreeOnTerminate := False;  // Controlamos la liberación nosotros
  FStopEvent := CreateEvent(nil, True, False, nil); // Manual reset, initially non-signaled
  DM.Log('INFO', 'WATCHDOG', 'Hilo de monitoreo iniciado', '');
end;

destructor TDirectoryWatchdog.Destroy;
begin
  if FStopEvent <> 0 then
    CloseHandle(FStopEvent);
  inherited;
end;

procedure TDirectoryWatchdog.SignalStop;
begin
  Terminate;
  if FStopEvent <> 0 then
    SetEvent(FStopEvent);
end;

procedure TDirectoryWatchdog.Execute;
begin
  while not Terminated do
  begin
    try
      ScanDirectory;
    except
      on E: Exception do
      begin
        try
          DM.Log('ERROR', 'WATCHDOG', 'Excepción en ciclo principal: ' + E.Message, '');
        except
          // Ignorar errores de log si la DB no está disponible
        end;
      end;
    end;

    // Espera interrumpible: se despierta inmediatamente si se señaliza FStopEvent
    if WaitForSingleObject(FStopEvent, 5000) = WAIT_OBJECT_0 then
      Break; // Se ha solicitado parar
  end;
end;

procedure TDirectoryWatchdog.ScanDirectory;
var
  Files: TArray<string>;
  FileName: string;
begin
  if (Config.PathRecepcion = '') or (not TDirectory.Exists(Config.PathRecepcion)) then
  begin
    DM.Log('ERROR', 'WATCHDOG', 'La carpeta de recepción no existe: ' + Config.PathRecepcion, '');
    Exit;
  end;

  Files := TDirectory.GetFiles(Config.PathRecepcion);
  for FileName in Files do
  begin
    if Terminated then Break; // Salir rápido si se pide terminar
    
    // Ignorar archivos temporales o de sistema
    if TPath.GetExtension(FileName).ToLower = '.tmp' then Continue;
    
    DM.Log('INFO', 'WATCHDOG', 'Procesando archivo detectado', TPath.GetFileName(FileName));
    try
      TDocumentProcessor.ProcessFile(FileName);
    except
      on E: Exception do
        DM.Log('ERROR', 'WATCHDOG', 'Error procesando: ' + E.Message, TPath.GetFileName(FileName));
    end;
  end;
end;

end.
