diff --git a/.plans/CreateLibNextcloud.md b/.plans/CreateLibNextcloud.md new file mode 100644 index 0000000..4c11a4f --- /dev/null +++ b/.plans/CreateLibNextcloud.md @@ -0,0 +1,749 @@ +# libnextcloud Shared Library Plan + +**Created**: 2026-01-27 +**Status**: 📋 Planning +**Target**: Cross-platform C++17 shared library for Nextcloud connectivity +**Branch**: `create-libnextcloud` + +--- + +## Overview + +Create `libnextcloud` - a cross-platform C++17 shared library that provides Nextcloud connectivity for embedded devices and homebrew platforms. The library will handle all Nextcloud communication, authentication, file operations, and settings management through a clean, platform-agnostic API. + +**Design Philosophy**: +- **Platform-agnostic**: Works on 3DS, Switch, Wii U, Vita, PC, etc. +- **Minimal dependencies**: Only libcurl, mbedTLS, and tinyxml2 +- **Header-only where possible**: nlohmann/json for configuration +- **Modern C++17**: Using standard library features +- **Testable**: Mock-friendly design with dependency injection +- **Documented**: Doxygen API documentation + +--- + +## Project Structure + +``` +shared/ +├── include/ +│ └── nextcloud/ +│ ├── client.hpp # Main client interface +│ ├── webdav_client.hpp # WebDAV protocol implementation +│ ├── auth.hpp # Authentication manager +│ ├── upload_manager.hpp # File upload with chunking +│ ├── folder_manager.hpp # Remote folder operations +│ ├── config.hpp # Configuration management +│ ├── types.hpp # Common types and enums +│ └── version.hpp # Library version info +├── src/ +│ ├── webdav_client.cpp +│ ├── auth.cpp +│ ├── upload_manager.cpp +│ ├── folder_manager.cpp +│ └── config.cpp +├── tests/ +│ ├── webdav_client_test.cpp +│ ├── auth_test.cpp +│ ├── upload_manager_test.cpp +│ ├── folder_manager_test.cpp +│ ├── config_test.cpp +│ └── mocks/ +│ ├── mock_http_client.hpp +│ └── mock_xml_parser.hpp +├── examples/ +│ ├── simple_upload.cpp +│ ├── folder_listing.cpp +│ └── authentication.cpp +├── docs/ +│ ├── api.md # API documentation +│ ├── architecture.md # Design overview +│ └── Doxyfile # Doxygen configuration +├── CMakeLists.txt +└── README.md +``` + +--- + +## Dependencies + +### Required +- **libcurl** (7.68+): HTTP/HTTPS client +- **mbedTLS** (2.16+): SSL/TLS support (works on embedded) +- **tinyxml2** (9.0+): Lightweight XML parsing + +### Header-Only +- **nlohmann/json** (3.10+): JSON parsing/serialization + +### Testing +- **Google Test** (1.11+): Unit testing framework +- **Google Mock** (1.11+): Mocking framework + +### Build Tools +- **CMake** (3.15+): Build system +- **C++17 compiler**: GCC 7+, Clang 5+, MSVC 2017+ + +--- + +## Implementation Phases + +## Phase 1: Project Scaffolding (Issue #??) + +**Goal**: Set up the library project structure and build system. + +### Tasks +- [ ] Create `shared/` directory structure +- [ ] Set up CMakeLists.txt with: + - Library target (static/shared) + - C++17 standard + - Include directories + - Dependency linking (curl, mbedtls, tinyxml2) + - Install rules + - Export config for downstream projects +- [ ] Create version.hpp with semantic versioning +- [ ] Create types.hpp with common enums and structures: + - `NextcloudError` enum + - `UploadProgress` struct + - `FileInfo` struct + - `FolderInfo` struct +- [ ] Set up Google Test framework +- [ ] Create basic README for the library +- [ ] Add pkg-config file generation +- [ ] Verify library compiles as standalone project + +### Acceptance Criteria +- [ ] CMake builds library successfully +- [ ] Can link against library from test project +- [ ] Version info accessible at runtime +- [ ] Ready for component implementation + +**Estimated Time**: 4-6 hours +**Priority**: Critical (blocks all other work) + +--- + +## Phase 2: WebDAV Client (Issue #8) + +**Goal**: Implement HTTP/WebDAV communication layer. + +### Tasks +- [ ] Create `webdav_client.hpp` interface +- [ ] Implement HTTP wrapper around libcurl: + - GET, PUT, POST, DELETE, custom methods + - Request/response headers + - Request body (string, stream) + - Response body handling + - Timeout configuration + - User-Agent setting +- [ ] Add SSL/TLS support with mbedTLS +- [ ] Implement WebDAV methods: + - PROPFIND (list files/folders) + - MKCOL (create folder) + - PUT (upload file) + - DELETE (remove file/folder) + - MOVE (rename/move) + - COPY (duplicate) +- [ ] Parse WebDAV XML responses (using tinyxml2): + - Multi-status responses + - File properties (size, mtime, type) + - Error responses +- [ ] Implement error handling: + - HTTP status codes + - Network errors + - XML parsing errors + - Error code mapping +- [ ] Add timeout and retry logic +- [ ] Write unit tests with mocked HTTP +- [ ] Document API in Doxygen format + +### API Design +```cpp +class WebDAVClient { +public: + WebDAVClient(const std::string& baseUrl); + + // Core HTTP + Response get(const std::string& path); + Response put(const std::string& path, const std::vector& data); + Response delete_(const std::string& path); + + // WebDAV operations + std::vector propfind(const std::string& path, int depth = 1); + bool mkcol(const std::string& path); + bool move(const std::string& from, const std::string& to); + bool copy(const std::string& from, const std::string& to); + + // Configuration + void setTimeout(int seconds); + void setAuthHeader(const std::string& header); +}; +``` + +### Acceptance Criteria +- [ ] All WebDAV methods implemented +- [ ] SSL/TLS connections working +- [ ] XML responses correctly parsed +- [ ] Error handling comprehensive +- [ ] Unit tests with >80% coverage +- [ ] API documented +- [ ] Works with test Nextcloud servers + +**Estimated Time**: 12-16 hours +**Priority**: Critical (foundation for all features) +**Dependencies**: Phase 1 complete + +--- + +## Phase 3: Authentication System (Issue #9) + +**Goal**: Handle authentication with Nextcloud servers. + +### Tasks +- [ ] Create `auth.hpp` interface +- [ ] Implement HTTP Basic Authentication: + - Base64 encoding + - Authorization header generation + - Credential storage +- [ ] Add authentication verification: + - Test connection to server + - Validate credentials + - Return meaningful error codes +- [ ] Secure credential handling: + - In-memory only (no disk storage by default) + - Platform-specific secure storage hooks +- [ ] Session management: + - Keep-alive connections + - Connection pooling + - Timeout handling +- [ ] Future: OAuth2 support (stubbed for now) +- [ ] Write unit tests for auth flows +- [ ] Document security considerations + +### API Design +```cpp +class AuthManager { +public: + // Basic Auth + void setBasicAuth(const std::string& username, const std::string& password); + std::string getAuthHeader() const; + + // Verification + bool verifyConnection(WebDAVClient& client); + + // Session management + void clearCredentials(); + bool hasCredentials() const; +}; +``` + +### Acceptance Criteria +- [ ] Basic auth working with real Nextcloud +- [ ] Credentials never logged or leaked +- [ ] Connection verification works +- [ ] Error messages helpful +- [ ] Unit tests cover edge cases +- [ ] API documented + +**Estimated Time**: 6-8 hours +**Priority**: High +**Dependencies**: Phase 2 complete + +--- + +## Phase 4: Upload Manager (Issue #10) + +**Goal**: Implement file upload with chunking and progress tracking. + +### Tasks +- [ ] Create `upload_manager.hpp` interface +- [ ] Implement streaming upload: + - Read file in chunks + - Send via PUT requests + - Handle large files (>1GB) +- [ ] Add chunking support: + - Configurable chunk size (default: 10MB) + - Resume capability (future) + - Parallel chunks (future) +- [ ] Progress tracking: + - Callback interface + - Bytes uploaded / total + - Transfer speed + - Time remaining estimate +- [ ] Error handling and retry: + - Network failures + - Server errors (503, 507) + - Automatic retry with backoff + - Partial upload cleanup +- [ ] Path handling: + - URL encoding + - Special characters + - Nested folders +- [ ] Write unit tests with mock uploads +- [ ] Document upload best practices + +### API Design +```cpp +class UploadManager { +public: + using ProgressCallback = std::function; + + UploadManager(WebDAVClient& client, AuthManager& auth); + + // Upload operations + bool uploadFile( + const std::string& localPath, + const std::string& remotePath, + ProgressCallback callback = nullptr + ); + + // Configuration + void setChunkSize(size_t bytes); + void setRetryCount(int count); + void setTimeout(int seconds); +}; + +struct UploadProgress { + std::string filename; + size_t bytesUploaded; + size_t totalBytes; + float percentComplete; + float bytesPerSecond; + int secondsRemaining; +}; +``` + +### Acceptance Criteria +- [ ] Uploads files successfully +- [ ] Chunking works for large files +- [ ] Progress callback accurate +- [ ] Handles network failures gracefully +- [ ] Retries work correctly +- [ ] Unit tests with various file sizes +- [ ] API documented + +**Estimated Time**: 10-12 hours +**Priority**: High +**Dependencies**: Phases 2, 3 complete + +--- + +## Phase 5: Folder Management (Issue #11) + +**Goal**: Remote folder operations and navigation. + +### Tasks +- [ ] Create `folder_manager.hpp` interface +- [ ] Implement folder listing: + - List contents of remote folder + - Parse file metadata (size, mtime, type) + - Recursive listing support + - Filtering (files only, folders only) +- [ ] Folder creation: + - Create single folder + - Create nested folders (mkdir -p) + - Validate folder names +- [ ] Folder navigation: + - Path normalization + - Parent folder detection + - Breadcrumb generation +- [ ] Caching (optional): + - Cache folder contents + - TTL-based invalidation + - Memory limits +- [ ] Write unit tests +- [ ] Document folder operations + +### API Design +```cpp +class FolderManager { +public: + FolderManager(WebDAVClient& client, AuthManager& auth); + + // Folder operations + std::vector listFolder(const std::string& path); + bool createFolder(const std::string& path); + bool createFolders(const std::string& path); // mkdir -p + bool deleteFolder(const std::string& path); + bool folderExists(const std::string& path); + + // Navigation helpers + std::string getParentFolder(const std::string& path); + std::vector getBreadcrumbs(const std::string& path); +}; + +struct FileInfo { + std::string name; + std::string path; + bool isDirectory; + size_t size; + time_t modifiedTime; + std::string contentType; +}; +``` + +### Acceptance Criteria +- [ ] Lists folders correctly +- [ ] Creates folders successfully +- [ ] Handles nested paths +- [ ] Metadata parsing accurate +- [ ] Unit tests comprehensive +- [ ] API documented + +**Estimated Time**: 8-10 hours +**Priority**: Medium +**Dependencies**: Phases 2, 3 complete + +--- + +## Phase 6: Favorites and Recent Folders (Issue #12) + +**Goal**: Persistence layer for user preferences. + +### Tasks +- [ ] Create `config.hpp` interface +- [ ] Implement favorites management: + - Add favorite folder + - Remove favorite folder + - List favorites + - Reorder favorites +- [ ] Implement recent folders tracking: + - Auto-track used folders + - Configurable limit (default: 5) + - LRU eviction + - Duplicate detection +- [ ] JSON persistence: + - Save to file + - Load from file + - Handle missing/corrupt files + - Migration support +- [ ] Platform-specific paths: + - Linux: ~/.config/nextcloud-share/ + - 3DS: /nextcloud-share/ + - Switch: /switch/nextcloud-share/ +- [ ] Write unit tests +- [ ] Document config format + +### API Design +```cpp +class Config { +public: + Config(const std::string& configPath = ""); + + // Favorites + void addFavorite(const std::string& path, const std::string& name = ""); + void removeFavorite(const std::string& path); + std::vector getFavorites() const; + + // Recent folders + void addRecentFolder(const std::string& path); + std::vector getRecentFolders() const; + void setMaxRecentFolders(int count); + + // Persistence + bool load(); + bool save(); +}; + +struct FolderInfo { + std::string path; + std::string displayName; + time_t lastUsed; +}; +``` + +### Acceptance Criteria +- [ ] Favorites persist across restarts +- [ ] Recent folders tracked correctly +- [ ] JSON format clean and readable +- [ ] Handles missing config gracefully +- [ ] Unit tests cover edge cases +- [ ] API documented + +**Estimated Time**: 6-8 hours +**Priority**: Low +**Dependencies**: None (standalone) + +--- + +## Phase 7: Testing and Documentation (Issue #13) + +**Goal**: Comprehensive test coverage and documentation. + +### Tasks +- [ ] Achieve >80% code coverage +- [ ] Integration tests with real Nextcloud: + - Test against cloud.tomusan.com + - Test against disobedient.cloud + - Verify all operations work +- [ ] Mock server for offline testing: + - Mock HTTP responses + - Simulate errors + - Test edge cases +- [ ] Performance testing: + - Large file uploads + - Many small files + - Concurrent operations +- [ ] Generate Doxygen documentation +- [ ] Write architecture document +- [ ] Create usage examples +- [ ] Document build process +- [ ] Add API reference + +### Documentation Structure +``` +docs/ +├── api.md # Full API reference +├── architecture.md # Library design and internals +├── building.md # Build instructions +├── examples.md # Usage examples +├── testing.md # How to run tests +├── contributing.md # Contribution guidelines +└── changelog.md # Version history +``` + +### Acceptance Criteria +- [ ] All classes have Doxygen comments +- [ ] Code coverage >80% +- [ ] Integration tests pass +- [ ] Documentation complete +- [ ] Examples compile and run +- [ ] Ready for platform integration + +**Estimated Time**: 10-12 hours +**Priority**: High +**Dependencies**: All phases complete + +--- + +## Issues to Create + +Based on this plan, create the following Gitea issues: + +### Issue: Initialize libnextcloud Project Structure +**Labels**: library, setup, priority:critical +**Description**: +``` +Set up the shared library project structure and build system for libnextcloud. + +## Tasks +- [ ] Create `shared/` directory structure +- [ ] Set up CMakeLists.txt for library +- [ ] Create version.hpp and types.hpp +- [ ] Set up Google Test framework +- [ ] Create basic README +- [ ] Add pkg-config file generation +- [ ] Verify library compiles standalone + +## Dependencies +- libcurl 7.68+ +- mbedTLS 2.16+ +- tinyxml2 9.0+ +- Google Test 1.11+ + +## Acceptance Criteria +- [ ] CMake builds library successfully +- [ ] Can link against library from test project +- [ ] Version info accessible at runtime +- [ ] Ready for component implementation + +Estimated: 4-6 hours +Blocks: #8, #9, #10, #11, #12, #13 +``` + +### Keep Existing Issues (Update Dependencies) + +**Issue #8**: Design and implement WebDAV client +- Add dependency: "Requires libnextcloud scaffolding (new issue)" +- Priority: High +- Estimated: 12-16 hours + +**Issue #9**: Implement authentication system +- Add dependency: "Requires #8" +- Priority: High +- Estimated: 6-8 hours + +**Issue #10**: Implement file upload functionality +- Add dependency: "Requires #8, #9" +- Priority: High +- Estimated: 10-12 hours + +**Issue #11**: Implement folder management +- Add dependency: "Requires #8, #9" +- Priority: Medium +- Estimated: 8-10 hours + +**Issue #12**: Implement favorites and recent folders +- Priority: Low +- Estimated: 6-8 hours + +**Issue #13**: Write unit tests for shared library +- Add dependency: "Requires #8-#12" +- Priority: High +- Estimated: 10-12 hours + +--- + +## Build System Design + +### CMakeLists.txt Structure + +```cmake +cmake_minimum_required(VERSION 3.15) +project(libnextcloud VERSION 0.1.0 LANGUAGES CXX) + +# C++17 required +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Library sources +add_library(nextcloud + src/webdav_client.cpp + src/auth.cpp + src/upload_manager.cpp + src/folder_manager.cpp + src/config.cpp +) + +# Include directories +target_include_directories(nextcloud + PUBLIC + $ + $ + PRIVATE + ${CMAKE_CURRENT_SOURCE_DIR}/src +) + +# Dependencies +find_package(CURL REQUIRED) +find_package(MbedTLS REQUIRED) +find_package(tinyxml2 REQUIRED) + +target_link_libraries(nextcloud + PUBLIC + CURL::libcurl + MbedTLS::mbedtls + tinyxml2::tinyxml2 +) + +# Testing +if(BUILD_TESTING) + enable_testing() + add_subdirectory(tests) +endif() + +# Install rules +install(TARGETS nextcloud EXPORT nextcloudTargets) +install(DIRECTORY include/ DESTINATION include) +install(EXPORT nextcloudTargets + FILE nextcloudTargets.cmake + NAMESPACE nextcloud:: + DESTINATION lib/cmake/nextcloud +) +``` + +### Platform-Specific Considerations + +**Nintendo 3DS**: +- Static library only (no shared objects) +- mbedTLS available via dkp-pacman +- libcurl with 3DS patches +- Filesystem: `/nextcloud-share/config.json` + +**Nintendo Switch**: +- Static library +- Standard libcurl and mbedTLS +- Filesystem: `/switch/nextcloud-share/config.json` + +**Linux/PC**: +- Shared library (.so) or static +- System libcurl and mbedTLS +- Filesystem: `~/.config/nextcloud-share/config.json` + +--- + +## Testing Strategy + +### Unit Tests +- Mock all external dependencies (HTTP, filesystem) +- Test each class in isolation +- Cover edge cases and error conditions +- Fast execution (<1 second total) + +### Integration Tests +- Real HTTP requests to test Nextcloud servers +- Require valid credentials from config.json +- Test full workflows end-to-end +- Can be skipped if credentials not available + +### Performance Tests +- Upload 1GB file and measure time +- Upload 1000 small files +- Concurrent uploads +- Memory usage profiling + +### Test Configuration +```json +{ + "test": { + "servers": [ + { + "name": "tomusan", + "url": "https://cloud.tomusan.com", + "username": "test", + "password": "xxx" + }, + { + "name": "disobedient", + "url": "https://disobedient.cloud/nextcloud", + "username": "test", + "password": "xxx" + } + ] + } +} +``` + +--- + +## Timeline Estimate + +**Total Estimated Time**: 56-74 hours + +| Phase | Tasks | Estimated Time | +|-------|-------|----------------| +| 1. Scaffolding | Project setup | 4-6 hours | +| 2. WebDAV Client | HTTP/WebDAV implementation | 12-16 hours | +| 3. Authentication | Auth system | 6-8 hours | +| 4. Upload Manager | File uploads | 10-12 hours | +| 5. Folder Management | Folder operations | 8-10 hours | +| 6. Favorites/Recent | Config persistence | 6-8 hours | +| 7. Testing/Docs | Tests and docs | 10-12 hours | + +**Realistic Timeline**: 2-3 weeks working part-time (15-20 hrs/week) + +--- + +## Success Criteria + +The library is complete when: + +- ✅ All phases implemented and tested +- ✅ Code coverage >80% +- ✅ Integration tests pass with real Nextcloud +- ✅ API documentation complete +- ✅ Examples compile and run +- ✅ Can be integrated into 3DS app +- ✅ Ready for additional platforms (Switch, Wii U, etc.) + +--- + +## Next Steps + +1. **Review this plan** - Adjust scope, estimates, priorities +2. **Create Gitea issues** - One for scaffolding, update existing issues +3. **Start Phase 1** - Set up project structure +4. **Implement phases sequentially** - Each phase depends on previous +5. **Test continuously** - Don't defer testing to the end + +--- + +**Ready to proceed?** Let's create the issues and start building!