# Phase 6: Initial Porting

Port Go code to .NET 10 C#, working through the dependency graph bottom-up. This is the main implementation phase where the actual code is written.

## Objective

Implement every non-N/A module, feature, and test in the porting database. Work from leaf nodes (items with no unported dependencies) upward through the dependency graph. Keep the database current as work progresses.

## Prerequisites

- Phase 5 complete: all mappings verified, no collisions, naming validated
- Read and follow the [.NET Coding Standards](../../standards/dotnet-standards.md) — covers testing (xUnit 3 / Shouldly / NSubstitute), logging (Microsoft.Extensions.Logging + Serilog + LogContext), async patterns, and performance guidelines
- .NET solution structure created:
  - `dotnet/src/ZB.MOM.NatsNet.Server/ZB.MOM.NatsNet.Server.csproj`
  - `dotnet/src/ZB.MOM.NatsNet.Server.Host/ZB.MOM.NatsNet.Server.Host.csproj`
  - `dotnet/tests/ZB.MOM.NatsNet.Server.Tests/ZB.MOM.NatsNet.Server.Tests.csproj`
  - `dotnet/tests/ZB.MOM.NatsNet.Server.IntegrationTests/ZB.MOM.NatsNet.Server.IntegrationTests.csproj`
- Library dependencies (NuGet packages) added per Phase 3 mappings
- Verify readiness: `dotnet run --project tools/NatsNet.PortTracker -- phase check 5 --db porting.db`

## Source and Target Locations

- **Go source code** is located in the `golang/` folder (specifically `golang/nats-server/`)
- **.NET ported version** is located in the `dotnet/` folder

## Milestone Tracking

This phase corresponds to **Milestone 6** in [Gitea](https://gitea.dohertylan.com/dohertj2/natsnet/milestone/6). When starting this phase, verify the milestone is open. Assign relevant issues to this milestone as work progresses.

### Issue Updates

Each completion criterion has a corresponding Gitea issue. Update issues as you work:

- **Starting a criterion**: Add a comment noting work has begun
- **Blocked**: Add a comment describing the blocker
- **Complete**: Close the issue with a comment summarizing the result (e.g., counts, verification output)

Close issues via CLI:
```bash
curl -s -X PATCH "https://gitea.dohertylan.com/api/v1/repos/dohertj2/natsnet/issues/{N}" \
  -H "Content-Type: application/json" \
  -H "Authorization: token $GITEA_TOKEN" \
  -d '{"state":"closed"}'
```
Or close via the Gitea web UI.

## Porting Workflow

This is the core loop. Repeat until all items are complete.

### Step 1: Find ready items

Query for items whose dependencies are all ported (status `complete`, `verified`, or `n_a`):

```bash
dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
```

This returns modules and features that have no unported dependencies. Start with these.

### Step 2: Pick an item and mark as stub

Choose an item from the ready list. Mark it as `stub` to signal work has begun:

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature update <id> --status stub --db porting.db
```

### Step 3: Create the skeleton

In the .NET project, create the class and method skeleton based on the mapping:

1. Look up the mapping: `dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db`
2. Create the file at the correct path under `dotnet/src/ZB.MOM.NatsNet.Server/` following the namespace hierarchy
3. Add the class declaration, method signature, and a `throw new NotImplementedException()` body

For batch scaffolding of an entire module:

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub \
  --all-in-module <module_id> --db porting.db
```

### Step 4: Implement the logic

Reference the Go source code. The database stores the Go file path and line number for each feature:

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature show <id> --db porting.db
```

The output includes `Go File`, `Go Line`, and `Go LOC` fields. Open the Go source at those coordinates and translate the logic to C#.

Key translation patterns:

| Go pattern | .NET equivalent |
|-----------|-----------------|
| `goroutine` + `channel` | `Task` + `Channel<T>` or `async/await` |
| `sync.Mutex` | `lock` statement or `SemaphoreSlim` |
| `sync.RWMutex` | `ReaderWriterLockSlim` |
| `sync.WaitGroup` | `Task.WhenAll` or `CountdownEvent` |
| `defer` | `try/finally` or `using`/`IDisposable` |
| `interface{}` / `any` | `object` or generics |
| `[]byte` | `byte[]`, `ReadOnlySpan<byte>`, or `ReadOnlyMemory<byte>` |
| `map[K]V` | `Dictionary<K,V>` or `ConcurrentDictionary<K,V>` |
| `error` return | Exceptions or `Result<T>` pattern |
| `panic/recover` | Exceptions (avoid `Environment.FailFast` for recoverable cases) |
| `select` on channels | `Task.WhenAny` or `Channel<T>` reader patterns |
| `context.Context` | `CancellationToken` |
| `io.Reader/Writer` | `Stream`, `PipeReader/PipeWriter` |

### Step 5: Mark complete

Once the implementation compiles and the basic logic is in place:

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature update <id> --status complete --db porting.db
```

### Step 6: Run targeted tests

If tests exist for this feature, run them:

```bash
dotnet test --filter "FullyQualifiedName~ZB.MOM.NatsNet.Server.Tests.Protocol" \
  dotnet/tests/ZB.MOM.NatsNet.Server.Tests/
```

Fix any failures before moving on.

### Step 7: Check what is now unblocked

Completing items may unblock others that depend on them:

```bash
dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
```

Return to Step 2 with the newly available items.

## DB Update Discipline

The porting database must stay current. Update status at every transition:

```bash
# Starting work on a feature
dotnet run --project tools/NatsNet.PortTracker -- feature update 42 --status stub --db porting.db

# Feature implemented
dotnet run --project tools/NatsNet.PortTracker -- feature update 42 --status complete --db porting.db

# Batch scaffolding for all features in a module
dotnet run --project tools/NatsNet.PortTracker -- feature update 0 --status stub \
  --all-in-module 3 --db porting.db

# Module fully ported (all its features are complete)
dotnet run --project tools/NatsNet.PortTracker -- module update 3 --status complete --db porting.db

# Check progress
dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db
```

Status transitions follow this progression:

```
not_started -> stub -> complete -> verified (Phase 7)
                  \-> n_a (if determined during porting)
```

Never skip `stub` -- it signals that work is in progress and prevents duplicate effort.

## Porting Order Strategy

### Start with leaf modules

Leaf modules have no dependencies on other unported modules. They are safe to port first because nothing they call is missing.

```bash
# These are the leaves — port them first
dotnet run --project tools/NatsNet.PortTracker -- dependency ready --db porting.db
```

Typical leaf modules include:
- Utility/helper code (string manipulation, byte buffer pools)
- Constants and enums
- Configuration types (options, settings)
- Error types and codes

### Then work upward

After leaves are done, modules that depended only on those leaves become ready. Continue up the dependency graph:

```
Leaf utilities -> Protocol types -> Parser -> Connection handler -> Server
```

### Server module session plan

The server module (~103K Go LOC, 3,394 features, 3,137 tests) is too large for a single pass. It has been broken into **23 sessions** with dependency ordering and sub-batching guidance. See [phase6sessions/readme.md](phase6sessions/readme.md) for the full session map, dependency graph, and execution instructions.

### Port tests alongside features

When porting a feature, also port its associated tests in the same pass. This provides immediate validation:

```bash
# List tests for a feature
dotnet run --project tools/NatsNet.PortTracker -- test list --module <module_id> --db porting.db

# After porting a test
dotnet run --project tools/NatsNet.PortTracker -- test update <id> --status complete --db porting.db
```

## Progress Tracking

Check overall progress regularly:

```bash
# Summary stats
dotnet run --project tools/NatsNet.PortTracker -- report summary --db porting.db

# What is still blocked
dotnet run --project tools/NatsNet.PortTracker -- dependency blocked --db porting.db

# Phase-level check
dotnet run --project tools/NatsNet.PortTracker -- phase check 6 --db porting.db
```

## Handling Discoveries During Porting

During implementation, you may find:

### Items that should be N/A

If a feature turns out to be unnecessary in .NET (discovered during implementation):

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature set-na <id> \
  --reason "Go-specific memory management, handled by .NET GC" --db porting.db
```

### Missing dependencies

If the Go analyzer missed a dependency:

```bash
# The dependency is tracked in the DB via the dependencies table
# For now, just ensure the target is ported before continuing
dotnet run --project tools/NatsNet.PortTracker -- dependency show feature <id> --db porting.db
```

### Design changes

If the .NET design needs to differ from the original mapping (e.g., splitting a large Go function into multiple .NET methods), update the mapping:

```bash
dotnet run --project tools/NatsNet.PortTracker -- feature map <id> \
  --class "NewClassName" \
  --method "NewMethodName" \
  --db porting.db
```

## Tips

1. **Keep the build green.** The solution should compile after each feature is completed. Do not leave unresolved references.
2. **Write idiomatic C#.** Do not transliterate Go line-by-line. Use .NET patterns (async/await, LINQ, Span, dependency injection) where they produce cleaner code.
3. **Use `CancellationToken` everywhere.** The Go code uses `context.Context` pervasively -- mirror this with `CancellationToken` parameters.
4. **Prefer `ReadOnlySpan<byte>` for hot paths.** The NATS parser processes bytes at high throughput. Use spans and avoid allocations in the critical path.
5. **Do not port Go comments verbatim.** Translate the intent into C# XML doc comments where appropriate.
6. **Run `dotnet build` frequently.** Catch compile errors early rather than accumulating them.

## Completion Criteria

- [ ] [#39](https://gitea.dohertylan.com/dohertj2/natsnet/issues/39) All non-N/A modules have status `complete` or better
- [ ] [#40](https://gitea.dohertylan.com/dohertj2/natsnet/issues/40) All non-N/A features have status `complete` or better
- [ ] [#41](https://gitea.dohertylan.com/dohertj2/natsnet/issues/41) All non-N/A tests have status `complete` or better
- [ ] [#42](https://gitea.dohertylan.com/dohertj2/natsnet/issues/42) The solution compiles without errors: `dotnet build`
- [ ] [#43](https://gitea.dohertylan.com/dohertj2/natsnet/issues/43) `dependency blocked` returns no items (or only items waiting for Phase 7 verification)
- [ ] [#44](https://gitea.dohertylan.com/dohertj2/natsnet/issues/44) `report summary` shows the expected completion counts
- [ ] Close the Phase 6 milestone in Gitea:
  ```bash
  curl -s -X PATCH "https://gitea.dohertylan.com/api/v1/repos/dohertj2/natsnet/milestones/6" \
    -H "Content-Type: application/json" \
    -H "Authorization: token $GITEA_TOKEN" \
    -d '{"state":"closed"}'
  ```
  Or close it via the Gitea web UI at https://gitea.dohertylan.com/dohertj2/natsnet/milestone/6

## Related Documentation

- [Phase 5: Mapping Verification](phase-5-mapping-verification.md) -- the verified mappings this phase implements
- [Phase 7: Porting Verification](phase-7-porting-verification.md) -- targeted testing of the ported code
