using System.Windows.Forms; using Remiss.Core; using Remiss.Core.Audit; using Remiss.Core.Models; using Remiss.Core.Printing; using Remiss.Core.Repositories; using Remiss.Core.Security; namespace Remiss.App; /// /// Entrypoint. Anropas av fångstlagret (Fas 2) eller manuellt (Fas 1) med /// sökväg till remiss-PDF:en som argument. /// /// Returkoder: /// 0 klart och utskrivet /// 1 fel under generering/merge/utskrift (temp städat) /// 2 ogiltigt/missande PDF-argument /// 3 användaren avbröt i dialogen /// 10 konfigurationsfel /// 11 fel i mottagningsregistret /// internal static class Program { [STAThread] private static int Main(string[] args) { ApplicationConfiguration.Initialize(); var baseDir = AppContext.BaseDirectory; AppConfig config; AuditLogger audit; try { config = AppConfig.Load(baseDir); audit = new AuditLogger(config.AuditLogPath, config.ErrorLogPath); } catch (Exception ex) { ShowError("Konfigurationsfel", ex.Message); return 10; } // [0] Ta emot och validera PDF-sökvägen. var sourceArg = args.FirstOrDefault(a => !a.StartsWith('-')); if (string.IsNullOrWhiteSpace(sourceArg)) { audit.Write("job.rejected", null, null, success: false, stage: "args", detail: "missing-path"); ShowError("Fel", "Ingen PDF-sökväg angavs som argument."); return 2; } var sourcePdf = Path.GetFullPath(sourceArg); if (!File.Exists(sourcePdf)) { audit.Write("job.rejected", null, null, success: false, stage: "args", detail: "file-not-found"); ShowError("Fel", $"Filen finns inte:\n{sourcePdf}"); return 2; } // [2] Läs mottagningsregistret. IReadOnlyList mottagningar; try { mottagningar = new JsonMottagningRepository(config.MottagningarPath).GetAll(); } catch (Exception ex) { audit.Write("job.rejected", null, null, success: false, stage: "registry", detail: ex.GetType().Name); audit.Error("registry", ex); ShowError("Fel", $"Kunde inte läsa mottagningsregistret:\n{ex.Message}"); return 11; } if (mottagningar.Count == 0) { ShowError("Fel", "Mottagningsregistret är tomt."); return 11; } // [1] Dialog: välj mottagning. Mottagning selected; using (var dialog = new MottagningDialog(mottagningar)) { if (dialog.ShowDialog() != DialogResult.OK || dialog.SelectedMottagning is null) { audit.Write("job.cancelled", null, null, success: false, stage: "dialog"); return 3; // inget temp skapat än – inget att städa } selected = dialog.SelectedMottagning; } // [3]–[6] Generera, merge, skriv ut, logga. Temp städas alltid. using var temp = new SecureTempStore(config.SecureTempRoot); try { var printer = new SumatraPdfPrinter(config.SumatraPdfPath, config.PrintRetries, config.PrintRetryDelayMs); new RemissWorkflow(config, printer, audit).Run(sourcePdf, selected, temp); return 0; } catch (Exception ex) { ShowError("Utskrift misslyckades", $"Remissen till {selected.Namn} kunde inte skickas.\n\n{ex.Message}\n\nTemporära filer har raderats."); return 1; } } private static void ShowError(string title, string message) => MessageBox.Show(message, title, MessageBoxButtons.OK, MessageBoxIcon.Error); }