package filemanager import ( "encoding/json" "log" "github.com/nats-io/nats.go" ) // HandleNatsRequest is the NATS message handler for the file manager command // subject (corrosion.{license_id}.files.cmd). It deserialises the request, // routes to the correct FileManager operation, and calls msg.Respond with a // NatsResponse JSON payload — either success with data or a structured error. func (fm *FileManager) HandleNatsRequest(msg *nats.Msg) { var req NatsRequest if err := json.Unmarshal(msg.Data, &req); err != nil { log.Printf("filemanager: invalid NATS request payload: %v", err) respondError(msg, "invalid request: "+err.Error()) return } log.Printf("filemanager: handling %s path=%q", req.Func, req.Path) switch req.Func { // ----------------------------------------------------------------------- // Directory listing // ----------------------------------------------------------------------- case FuncList: result, err := fm.List(req.Path) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, result) // ----------------------------------------------------------------------- // Delete // ----------------------------------------------------------------------- case FuncDelete: result, err := fm.Delete(req.Path, req.Items) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, result) // ----------------------------------------------------------------------- // Rename — req.Name holds the new basename // ----------------------------------------------------------------------- case FuncRename: if len(req.Items) == 0 { respondError(msg, "rename requires at least one item") return } result, err := fm.Rename(req.Path, req.Items[0], req.Name) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, result) // ----------------------------------------------------------------------- // Copy // ----------------------------------------------------------------------- case FuncCopy: if req.Destination == "" { respondError(msg, "copy requires a destination path") return } result, err := fm.Copy(req.Path, req.Items, req.Destination) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, result) // ----------------------------------------------------------------------- // Move // ----------------------------------------------------------------------- case FuncMove: if req.Destination == "" { respondError(msg, "move requires a destination path") return } result, err := fm.Move(req.Path, req.Items, req.Destination) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, result) // ----------------------------------------------------------------------- // Create directory // ----------------------------------------------------------------------- case FuncCreateFolder: if req.Name == "" { respondError(msg, "mkdir requires a folder name") return } result, err := fm.CreateFolder(req.Path, req.Name) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, result) // ----------------------------------------------------------------------- // Create empty file // ----------------------------------------------------------------------- case FuncCreateFile: if req.Name == "" { respondError(msg, "mkfile requires a file name") return } result, err := fm.CreateFile(req.Path, req.Name) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, result) // ----------------------------------------------------------------------- // Search // ----------------------------------------------------------------------- case FuncSearch: result, err := fm.Search(req.Path, req.Filter) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, result) // ----------------------------------------------------------------------- // Preview / read file content (VueFinder uses "fm_preview" for text files) // ----------------------------------------------------------------------- case FuncPreview: content, err := fm.GetContent(req.Path) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, map[string]string{"content": content}) // ----------------------------------------------------------------------- // Save file content // ----------------------------------------------------------------------- case FuncSave: if err := fm.SaveContent(req.Path, req.Content); err != nil { respondError(msg, err.Error()) return } respondJSON(msg, map[string]string{"status": "saved"}) // ----------------------------------------------------------------------- // Upload — content arrives as a base64-encoded string // ----------------------------------------------------------------------- case FuncUpload: if req.Filename == "" { respondError(msg, "upload requires a filename") return } data, err := DecodeBase64(req.Content) if err != nil { respondError(msg, err.Error()) return } result, err := fm.Upload(req.Path, req.Filename, data) if err != nil { respondError(msg, err.Error()) return } respondJSON(msg, result) // ----------------------------------------------------------------------- // Unknown function // ----------------------------------------------------------------------- default: log.Printf("filemanager: unknown function %q", req.Func) respondError(msg, "unknown function: "+req.Func) } } // --------------------------------------------------------------------------- // Response helpers // --------------------------------------------------------------------------- // respondJSON sends a successful NatsResponse wrapping data. func respondJSON(msg *nats.Msg, data interface{}) { resp := NatsResponse{Success: true, Data: data} bytes, err := json.Marshal(resp) if err != nil { log.Printf("filemanager: failed to marshal success response: %v", err) respondError(msg, "internal: failed to marshal response") return } if err := msg.Respond(bytes); err != nil { log.Printf("filemanager: failed to send response: %v", err) } } // respondError sends a failed NatsResponse with the given error message. func respondError(msg *nats.Msg, errMsg string) { resp := NatsResponse{Success: false, Error: errMsg} bytes, _ := json.Marshal(resp) if err := msg.Respond(bytes); err != nil { log.Printf("filemanager: failed to send error response: %v", err) } }