# Architecture **Analysis Date:** 2026-05-18 ## Pattern Overview **Overall:** Layered CLI console application with abstract machine interface, factory dispatch, and offline license gate. **Key Characteristics:** - Single Windows EXE (all dependencies embedded via Costura.Fody) - Polymorphic multi-vendor CNC support via `ICncMachine` interface - Factory pattern for manufacturer selection at runtime - Async/await throughout (Task-based), but blocked at CLI boundary via `.GetAwaiter().GetResult()` - Result-wrapper pattern (`CncResult`) instead of exceptions for CNC operations - RSA license validation gate on every startup ## Layers **CLI Entry Layer:** - Purpose: Parse args, validate license, dispatch to action (Scarica/Invia) - Contains: `Program.cs` (main orchestration), `ArgParser.cs` (regex arg parsing), `InputArgs.cs` (config object) - Depends on: Licensing layer, CNC abstraction layer - Error output: Negative exit codes (-100 to -208) mapped to Italian user messages **Licensing Layer:** - Purpose: Prevent execution on unlicensed machines - Contains: `Licensing/LicenseValidator.cs`, `Licensing/MachineFingerprint.cs`, `Licensing/LicenseFile.cs` - Depends on: WMI (System.Management), RSA crypto - Used by: CLI entry layer (startup check only) **CNC Abstraction Layer:** - Purpose: Uniform interface over 4 different CNC protocols - Contains: `Cnc/ICncMachine.cs`, `Cnc/IFanucMachine.cs`, `Cnc/CncMachineFactory.cs`, `Cnc/Models/` - Key types: `CncResult`, `CncError`, `CncManufacturer`, `ConnectionState`, `CncProgram` - Used by: CLI entry layer **Manufacturer Implementations:** - Purpose: Protocol-specific CNC communication - Contains: `Cnc/Fanuc/`, `Cnc/Heidenhain/`, `Cnc/Siemens/`, `Cnc/Mitsubishi/` - Each implements `ICncMachine` (Fanuc also implements `IFanucMachine`) - Depends on: Protocol libraries (FOCAS DLL, TCP socket, FtpWebRequest) **Validation Layer:** - Purpose: Pre-upload NC program syntax checking - Contains: `Cnc/INcProgramValidator.cs`, `Cnc/NcProgramValidator.cs` - Injected into machine implementations; upload blocked on Error severity - Depends on: Nothing external **NC Program Parsing:** - Purpose: Parse/format Fanuc composite NC file format - Contains: `FanucProgram.cs` (program + tooloffset + workzero sections) - Used by: CLI entry layer post-download ## Data Flow **Scarica (Download from CNC):** ``` CLI args → ArgParser.Parse() → InputArgs → LicenseValidator.Validate() [exit -1xx on failure] → CncMachineFactory.Create(InputArgs) → ICncMachine → machine.ConnectAsync() → CncResult → machine.ReadProgramAsync(path) → CncResult → [IFanucMachine cast] ReadToolDataAsync / ReadWorkZeroDataAsync → FanucProgram.Format() → composite file string → File.WriteAllText(localPath) ``` **Invia (Upload to CNC):** ``` CLI args → ArgParser.Parse() → InputArgs → LicenseValidator.Validate() [exit -1xx on failure] → CncMachineFactory.Create(InputArgs) → ICncMachine → File.ReadAllText(localPath) → NcProgramValidator.Validate() [exit on Error severity] → machine.ConnectAsync() → machine.WriteProgramAsync(path, content) → CncResult ``` **State Management:** - No persistent in-memory state between invocations (each run is independent) - Machine state tracked per-instance: `ConnectionState` enum + `StateChanged` event - Thread safety: `SemaphoreSlim` gate per machine instance ## Key Abstractions **ICncMachine:** - Purpose: Uniform contract for all CNC machines - Location: `Cnc/ICncMachine.cs` - Methods: `ConnectAsync`, `DisconnectAsync`, `ReadProgramAsync`, `WriteProgramAsync`, `ReadAsync`, `DeleteProgramAsync`, `ReadActiveProgramAsync`, `SelectMainProgramAsync` - Pattern: Interface + factory dispatch **IFanucMachine:** - Purpose: Fanuc-specific extensions (tool offsets, work zero) - Location: `Cnc/IFanucMachine.cs` - Extends: `ICncMachine` - Pattern: Interface specialization **CncResult:** - Purpose: Typed result wrapper replaces exception-based control flow - Location: `Cnc/Models/CncResult.cs` - Factories: `Ok()`, `Fail()`, `Cancelled()`, `OkWithWarnings()` - Properties: `Success`, `Errors`, `WasCancelled`, `Value` **IFocasDialect:** - Purpose: Abstract FOCAS version differences (Legacy vs Modern API) - Location: `Cnc/Fanuc/IFocasDialect.cs` - Implementations: `LegacyFocasDialect.cs`, `ModernFocasDialect.cs` - Detection: `FanucDialectDetector.cs` at connect time **CncMachineFactory:** - Purpose: Create correct ICncMachine from InputArgs - Location: `Cnc/CncMachineFactory.cs` - Dispatches on: `CncManufacturer` enum (Fanuc, Heidenhain, Siemens, Mitsubishi) ## Entry Points **CLI Entry:** - Location: `Program.cs` (Main method) - Triggers: Process execution from command line or calling application - Responsibilities: Arg parsing → license check → machine factory → action dispatch → exit code **Argument Parser:** - Location: `ArgParser.cs` (static `Parse(string[])`) - Returns: `InputArgs` with all 16 CLI parameters normalized ## Error Handling **Strategy:** Result wrapper at CNC layer, exit codes at CLI boundary, ArgumentNullException for null guards **Patterns:** - `CncResult.Fail(errors)` for CNC operation failures - `ArgumentNullException` for constructor null guards (`Cnc/Fanuc/FanucMachine.cs`) - Exit codes -100 to -208 in `Program.cs` for user-facing errors - `try/finally` with `connected` flag for connection leak prevention (`Program.cs`) - `catch { }` (silent) on disconnect cleanup paths — known weakness (see CONCERNS.md) ## Cross-Cutting Concerns **Logging:** - `Console.WriteLine` only — no structured logging framework - Debug mode (`-debug=` arg): keeps terminal open after operation **Validation:** - `NcProgramValidator` injected into machine constructors - Runs before upload; blocked on `ValidationSeverity.Error` **Cancellation:** - `CancellationToken` passed through all async methods - CLI does not currently expose cancellation to user --- *Architecture analysis: 2026-05-18* *Update when major patterns change*