package handlers import ( "context" "fmt" "io" "os" "path/filepath" "strconv" "github.com/stormlightlabs/noteleaf/internal/store" "github.com/stormlightlabs/noteleaf/internal/utils" ) // ParseID converts a string ID to int64 func ParseID(id string, itemType string) (int64, error) { itemID, err := strconv.ParseInt(id, 10, 64) if err != nil { return 0, fmt.Errorf("invalid %s ID: %s", itemType, id) } return itemID, nil } // Setup initializes the application database and configuration func Setup(ctx context.Context, args []string) error { logger := utils.GetLogger() logger.Info("Setting up noteleaf") configDir, err := store.GetConfigDir() if err != nil { logger.Error("Failed to get config directory", "error", err) return fmt.Errorf("failed to get config directory: %w", err) } logger.Info("Using config directory", "path", configDir) fmt.Printf("Config directory: %s\n", configDir) config, err := store.LoadConfig() if err != nil { return fmt.Errorf("failed to load configuration: %w", err) } var dbPath string if config.DatabasePath != "" { dbPath = config.DatabasePath } else if config.DataDir != "" { dbPath = filepath.Join(config.DataDir, "noteleaf.db") } else { dataDir, err := store.GetDataDir() if err != nil { return fmt.Errorf("failed to get data directory: %w", err) } dbPath = filepath.Join(dataDir, "noteleaf.db") } if _, err := os.Stat(dbPath); err == nil { fmt.Println("Database already exists. Use --force to recreate.") return nil } db, err := store.NewDatabase() if err != nil { return fmt.Errorf("failed to initialize database: %w", err) } defer db.Close() fmt.Printf("Database created: %s\n", db.GetPath()) configPath, err := store.GetConfigPath() if err != nil { return fmt.Errorf("failed to get config path: %w", err) } fmt.Printf("Configuration created: %s\n", configPath) fmt.Printf("Date format: %s\n", config.DateFormat) fmt.Printf("Color scheme: %s\n", config.ColorScheme) fmt.Printf("Default view: %s\n", config.DefaultView) runner := store.NewMigrationRunner(db) migrations, err := runner.GetAppliedMigrations() if err != nil { return fmt.Errorf("failed to get migration status: %w", err) } fmt.Printf("Applied migrations: %d\n", len(migrations)) for _, m := range migrations { fmt.Printf(" - %s (%s)\n", m.Version, m.AppliedAt) } fmt.Println("Setup completed successfully!") fmt.Println("\nYou can now use noteleaf commands:") fmt.Println(" noteleaf add \"Buy groceries\"") fmt.Println(" noteleaf list") fmt.Println(" noteleaf movie add \"The Matrix\"") return nil } // Reset recreates the database and configuration (destructive) func Reset(ctx context.Context, args []string) error { fmt.Println("Resetting noteleaf...") config, err := store.LoadConfig() if err != nil { config = store.DefaultConfig() } var dbPath string if config.DatabasePath != "" { dbPath = config.DatabasePath } else if config.DataDir != "" { dbPath = filepath.Join(config.DataDir, "noteleaf.db") } else { dataDir, err := store.GetDataDir() if err != nil { return fmt.Errorf("failed to get data directory: %w", err) } dbPath = filepath.Join(dataDir, "noteleaf.db") } if err := os.Remove(dbPath); err != nil && !os.IsNotExist(err) { return fmt.Errorf("failed to remove database: %w", err) } configPath, err := store.GetConfigPath() if err != nil { return fmt.Errorf("failed to get config path: %w", err) } if err := os.Remove(configPath); err != nil && !os.IsNotExist(err) { return fmt.Errorf("failed to remove config: %w", err) } fmt.Println("Reset completed. Run 'noteleaf setup' to reinitialize.") return nil } // Status shows the current application status func Status(ctx context.Context, args []string, w io.Writer) error { configDir, err := store.GetConfigDir() if err != nil { return fmt.Errorf("failed to get config directory: %w", err) } fmt.Printf("Config directory: %s\n", configDir) config, err := store.LoadConfig() if err != nil { return fmt.Errorf("failed to load configuration: %w", err) } var dbPath string if config.DatabasePath != "" { dbPath = config.DatabasePath } else if config.DataDir != "" { dbPath = filepath.Join(config.DataDir, "noteleaf.db") } else { dataDir, err := store.GetDataDir() if err != nil { return fmt.Errorf("failed to get data directory: %w", err) } dbPath = filepath.Join(dataDir, "noteleaf.db") } if _, err := os.Stat(dbPath); err != nil { fmt.Fprintln(w, "Database: Not found") fmt.Fprintln(w, "Run 'noteleaf setup' to initialize.") return nil } fmt.Fprintf(w, "Database: %s\n", dbPath) configPath, err := store.GetConfigPath() if err != nil { return fmt.Errorf("failed to get config path: %w", err) } if _, err := os.Stat(configPath); err != nil { fmt.Fprintln(w, "Configuration: Not found") } else { fmt.Fprintf(w, "Configuration: %s\n", configPath) } db, err := store.NewDatabase() if err != nil { return fmt.Errorf("failed to connect to database: %w", err) } defer db.Close() runner := store.NewMigrationRunner(db) applied, err := runner.GetAppliedMigrations() if err != nil { return fmt.Errorf("failed to get applied migrations: %w", err) } available, err := runner.GetAvailableMigrations() if err != nil { return fmt.Errorf("failed to get available migrations: %w", err) } fmt.Fprintf(w, "Migrations: %d/%d applied\n", len(applied), len(available)) return nil }