package backup import ( "backea/internal/mail" "context" "fmt" "log" "os" "os/exec" "time" ) // Service represents a service to be backed up type Service struct { Name string Directory string Strategy Strategy Mailer *mail.Mailer } // NewService creates a new backup service func NewService(name string, directory string, strategy Strategy, mailer *mail.Mailer) *Service { return &Service{ Name: name, Directory: directory, Strategy: strategy, Mailer: mailer, } } // Backup performs the backup for this service func (s *Service) Backup(ctx context.Context) error { log.Printf("Backing up service: %s", s.Name) startTime := time.Now() // Ensure directory exists if _, err := os.Stat(s.Directory); os.IsNotExist(err) { return fmt.Errorf("directory does not exist: %s", s.Directory) } // Execute the backup strategy if err := s.Strategy.Execute(ctx, s.Name, s.Directory); err != nil { if s.Mailer != nil { s.Mailer.SendErrorNotification(s.Name, err) } return fmt.Errorf("backup failed: %w", err) } // Record backup completion duration := time.Since(startTime) log.Printf("Backup completed for %s in %v", s.Name, duration) // Send success notification if s.Mailer != nil { s.Mailer.SendSuccessNotification(s.Name, duration) } return nil } // RunCommand executes a shell command in the specified directory // This is now a package function rather than a method on Service func RunCommand(dir, command string) error { cmd := exec.Command("sh", "-c", command) if dir != "" { cmd.Dir = dir } cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr return cmd.Run() }