package cli import ( "fmt" "log" "github.com/damirmukimov/city_resource_graph/models" "github.com/damirmukimov/city_resource_graph/models/output" "github.com/damirmukimov/city_resource_graph/models/params" ) // Calculator handles mathematical model calculations type Calculator struct { formatter *output.Formatter } // NewCalculator creates a new calculator instance func NewCalculator(format string) *Calculator { return &Calculator{ formatter: output.NewFormatter(format), } } // LoadAndValidateParams loads and validates parameters from file func (c *Calculator) LoadAndValidateParams(filepath string) (*params.Params, error) { // Load parameters p, err := params.LoadFromFile(filepath) if err != nil { return nil, fmt.Errorf("failed to load parameters from %s: %w", filepath, err) } // Validate parameters if err := p.Validate(); err != nil { return nil, fmt.Errorf("invalid parameters: %w", err) } return p, nil } // CalculateAndFormat runs the complete calculation and formats output func (c *Calculator) CalculateAndFormat(filepath string) error { // Load and validate parameters p, err := c.LoadAndValidateParams(filepath) if err != nil { return err } // Calculate all years result, err := models.Calculate(p) if err != nil { return fmt.Errorf("calculation failed: %w", err) } // Format and output result return c.formatter.FormatResult(result) } // ValidateOnly validates parameters without running calculations func (c *Calculator) ValidateOnly(filepath string) error { // Load parameters p, err := params.LoadFromFile(filepath) if err != nil { return fmt.Errorf("failed to load parameters from %s: %w", filepath, err) } // Validate parameters if err := p.Validate(); err != nil { return c.formatter.FormatValidation(false, []error{err}) } return c.formatter.FormatValidation(true, nil) } // SummaryOnly calculates and shows summary without full output func (c *Calculator) SummaryOnly(filepath string) error { // Set formatter to summary format c.formatter = output.NewFormatter("summary") return c.CalculateAndFormat(filepath) } // Logger provides structured logging for CLI operations type Logger struct{} // NewLogger creates a new logger func NewLogger() *Logger { return &Logger{} } // Info logs informational messages func (l *Logger) Info(msg string, args ...interface{}) { log.Printf("INFO: "+msg, args...) } // Error logs error messages func (l *Logger) Error(msg string, args ...interface{}) { log.Printf("ERROR: "+msg, args...) } // Fatal logs fatal errors and exits func (l *Logger) Fatal(msg string, args ...interface{}) { log.Fatalf("FATAL: "+msg, args...) }