package transfer import ( "context" "fmt" "io" "log" "os" "path/filepath" ) type NASTransfer struct { config NASConfig connected bool } func NewNASTransfer(config NASConfig) *NASTransfer { return &NASTransfer{ config: config, } } func (nt *NASTransfer) TransferFile(ctx context.Context, item *TransferItem) error { destPath := filepath.Join(nt.config.Path, item.DestinationPath) destDir := filepath.Dir(destPath) if err := nt.ensureDirectoryExists(destDir); err != nil { return fmt.Errorf("Failed to create directory %s: %w", destDir, err) } transferCtx, cancel := context.WithTimeout(ctx, nt.config.Timeout) defer cancel() if err := nt.copyFile(transferCtx, item.SourcePath, destPath); err != nil { return fmt.Errorf("Failed to copy file %s to %s: %w", item.SourcePath, destPath, err) } if nt.config.VerifySize { if err := nt.VerifyTransfer(item.SourcePath, destPath); err != nil { os.Remove(destPath) return fmt.Errorf("Failed to verify transfer: %w", err) } } log.Printf("File transfer completed: %s -> %s", item.SourcePath, destPath) return nil } func (nt *NASTransfer) copyFile(ctx context.Context, srcPath, destPath string) error { src, err := os.Open(srcPath) if err != nil { return fmt.Errorf("Failed to open source file: %w", err) } defer src.Close() dest, err := os.Create(destPath) if err != nil { return fmt.Errorf("Failed to create destination file: %w", err) } defer dest.Close() done := make(chan error, 1) go func() { _, err := io.Copy(dest, src) done <- err }() select { case <-ctx.Done(): return ctx.Err() case err := <-done: if err != nil { return err } return dest.Sync() } } func (nt *NASTransfer) VerifyTransfer(srcPath, destPath string) error { srcInfo, err := os.Stat(srcPath) if err != nil { return fmt.Errorf("Failed to stat source file: %w", err) } destInfo, err := os.Stat(destPath) if err != nil { return fmt.Errorf("Failed to stat destination file: %w", err) } if srcInfo.Size() != destInfo.Size() { return fmt.Errorf("size mismatch: source=%d, dest=%d", srcInfo.Size(), destInfo.Size()) } return nil } func (nt *NASTransfer) ensureDirectoryExists(path string) error { if err := os.MkdirAll(path, 0755); err != nil { return fmt.Errorf("Failed to create directory: %w", err) } return nil } func (nt *NASTransfer) TestConnection() error { testFile := filepath.Join(nt.config.Path, ".connection_test") f, err := os.Create(testFile) if err != nil { return fmt.Errorf("Failed to create test file: %w", err) } f.Close() os.Remove(testFile) nt.connected = true log.Printf("Connected to NAS at %s", nt.config.Path) return nil } func (nt *NASTransfer) IsConnected() bool { return nt.connected }