foxygit / digitalskrivare_merge Log in
commits tags

/src/Remiss.App/Program.cs · 3.73 KB

raw
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;

/// <summary>
/// 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
/// </summary>
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<Mottagning> 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);
}