# 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<T>`) 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<T>`, `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<bool>
  → machine.ReadProgramAsync(path) → CncResult<string>
  → [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<bool>
```

**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<T>:**
- 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<T>.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*
