ketotrack/main.go
2024-05-12 15:46:23 -04:00

163 lines
3.6 KiB
Go

package main
import (
"bufio"
"errors"
"fmt"
"os"
"path/filepath"
"strconv"
"strings"
"ketotrack/data"
"ketotrack/model"
)
var recordsFilename string
func init() {
// Get user's homeDir directory
homeDir, err := os.UserHomeDir()
if err != nil {
fmt.Println("Error fetching user's home directory:", err)
os.Exit(1)
}
// Define the path to the application data directory
ketotrackDir := filepath.Join(homeDir, ".ketotrack")
// Create the directory if it does not exist
err = os.MkdirAll(ketotrackDir, 0770)
if err != nil {
fmt.Println("Error creating .ketotrack directory:", err)
os.Exit(1)
}
// Set data file path for readings
recordsFilename = filepath.Join(ketotrackDir, "records.json")
}
func main() {
var appCtx data.AppContext
if err := appCtx.LoadRecords(recordsFilename); err != nil {
fmt.Printf("Error loading records from file: %s\n", err)
}
for {
choice, err := getUserInput("1. Enter new reading\n2. Enter new note\n3. Exit\nYour choice")
if err != nil {
fmt.Printf("Error reading choice: %s\n", err)
continue
}
if choice == "3" {
fmt.Println("Exiting...")
break
}
switch choice {
case "1":
// Get a new Reading from the user
reading, err := getReading()
if err != nil {
fmt.Printf("Error getting reading: %s\n", err)
} else {
appCtx.AddReading(reading)
}
case "2":
// Get a new Note from the user
note, err := getNote()
if err != nil {
fmt.Printf("Error getting note: %s\n", err)
} else {
appCtx.AddNote(note)
}
default:
fmt.Printf("Invalid choice, please try again.\n\n")
}
}
// Save Records before exiting
if err := appCtx.SaveRecords(recordsFilename); err != nil {
fmt.Printf("Error saving records to file: %s\n", err)
}
}
func getNote() (model.Note, error) {
text, err := getUserInput("Enter note text")
if err != nil {
return model.Note{}, err
}
return model.NewNote(text), nil
}
func getReading() (model.Reading, error) {
// Get glucose reading
glucose, err := getUserFloat("Enter glucose reading (mg/dL)")
if err != nil {
return model.Reading{}, fmt.Errorf("error getting glucose reading: %w", err)
}
// Validate glucose reading
if glucose <= 0 {
return model.Reading{}, errors.New("glucose reading cannot be less than or equal to 0")
}
// Get ketone reading
ketone, err := getUserFloat("Enter ketone reading (mmol/L)")
if err != nil {
return model.Reading{}, fmt.Errorf("error getting ketone reading: %w", err)
}
// Validate ketone reading
if ketone < 0 {
fmt.Println("")
return model.Reading{}, errors.New("ketone reading cannot be less than 0")
}
reading := model.NewReading(glucose, ketone)
// Display GKI and level of ketosis
fmt.Printf("\nYour GKI is: %0.2f\n", reading.GKI)
switch {
case reading.GKI <= 1:
fmt.Println("You're in the highest level of ketosis.")
case reading.GKI < 3:
fmt.Println("You're in a high therapeutic level of ketosis.")
case reading.GKI < 6:
fmt.Println("You're in a moderate level of ketosis.")
case reading.GKI <= 9:
fmt.Println("You're in a low level of ketosis.")
default:
fmt.Println("You are not in ketosis.")
}
return reading, nil
}
func getUserInput(prompt string) (string, error) {
fmt.Printf("%s: ", prompt)
reader := bufio.NewReader(os.Stdin)
input, err := reader.ReadString('\n')
if err != nil {
return "", err
}
return strings.TrimSpace(input), nil
}
func getUserFloat(prompt string) (float64, error) {
// Get input as a string
s, err := getUserInput(prompt)
if err != nil {
return 0, err
}
// Convert string to float
f, err := strconv.ParseFloat(s, 64)
if err != nil {
return 0, err
}
return f, nil
}