# Gitea .NET SDK

Official .NET SDK for the Gitea API with chunked upload support for large files.

## Installation

```bash
dotnet add package Gitea.SDK
```

## Quick Start

```csharp
using Gitea.SDK;

// Create client
var client = new GiteaClient("https://gitea.example.com", "your_token");

// Get current user
var user = await client.GetCurrentUserAsync();
Console.WriteLine($"Logged in as {user.Login}");

// Get a repository
var repo = await client.GetRepositoryAsync("owner", "repo");
Console.WriteLine($"Repository: {repo.FullName}");
```

## Chunked Upload

Upload large files with progress tracking:

```csharp
using Gitea.SDK;

var client = new GiteaClient("https://gitea.example.com", "your_token");

// Upload a release asset with progress
await using var fileStream = File.OpenRead("large-file.tar.gz");

var result = await client.UploadReleaseAssetAsync(
    owner: "myorg",
    repo: "myrepo",
    releaseId: 123,
    fileStream: fileStream,
    filename: "large-file.tar.gz",
    options: new ChunkedUploadOptions
    {
        ChunkSize = 50 * 1024 * 1024, // 50MB chunks
        Parallel = 4,
        VerifyChecksum = true,
        OnProgress = p =>
        {
            Console.WriteLine($"Progress: {p.Percent:F1}%");
            Console.WriteLine($"Speed: {p.SpeedFormatted}");
            Console.WriteLine($"ETA: {p.EtaFormatted}");
        }
    });

Console.WriteLine($"Uploaded: {result.BrowserDownloadUrl}");
```

## Using ChunkedUpload Directly

For more control over the upload process:

```csharp
using Gitea.SDK;

var client = new GiteaClient("https://gitea.example.com", "your_token");

var upload = client.CreateChunkedUpload("owner", "repo", 123, new ChunkedUploadOptions
{
    ChunkSize = 50 * 1024 * 1024,
    Parallel = 4,
    OnProgress = p => Console.WriteLine($"{p.Percent:F1}%")
});

try
{
    await using var stream = File.OpenRead("file.tar.gz");
    var result = await upload.UploadAsync(stream, "file.tar.gz");
    Console.WriteLine($"Success: {result.BrowserDownloadUrl}");
}
catch (UploadException ex)
{
    // Upload failed, can retry later
    Console.WriteLine($"Resume with session: {upload.Session?.Id}");
}
```

## API Reference

### GiteaClient

#### Constructor

```csharp
var client = new GiteaClient(
    baseUrl: "https://gitea.example.com",
    token: "your_api_token",
    httpClient: null // Optional custom HttpClient
);
```

#### User Methods

- `GetCurrentUserAsync()` - Get authenticated user
- `GetUserAsync(username)` - Get user by username

#### Repository Methods

- `GetRepositoryAsync(owner, repo)` - Get repository
- `ListUserRepositoriesAsync(username)` - List user's repositories

#### Release Methods

- `GetReleaseAsync(owner, repo, releaseId)` - Get release by ID
- `GetReleaseByTagAsync(owner, repo, tag)` - Get release by tag
- `ListReleasesAsync(owner, repo)` - List all releases

#### Upload Methods

- `UploadReleaseAssetAsync(...)` - Upload release asset with chunked upload
- `CreateChunkedUpload(owner, repo, releaseId, options)` - Create upload handler
- `GetUploadSessionAsync(sessionId)` - Get upload session status
- `CancelUploadAsync(sessionId)` - Cancel upload session

## Error Handling

```csharp
using Gitea.SDK;

var client = new GiteaClient("https://gitea.example.com", "your_token");

try
{
    var repo = await client.GetRepositoryAsync("owner", "nonexistent");
}
catch (NotFoundException ex)
{
    Console.WriteLine($"Repository not found: {ex.Message}");
}
catch (AuthenticationException ex)
{
    Console.WriteLine($"Authentication failed: {ex.Message}");
}
catch (UploadException ex)
{
    Console.WriteLine($"Upload failed: {ex.Message}");
    Console.WriteLine($"Session: {ex.SessionId}, Chunk: {ex.ChunkNumber}");
}
catch (ApiException ex)
{
    Console.WriteLine($"API error [{ex.Code}]: {ex.Message}");
}
```

## Requirements

- .NET 8.0 or later
- System.Text.Json for JSON serialization

## License

MIT License - See LICENSE file for details.
