package cli import ( "fmt" "strings" ) const ( ColorReset = "\033[0m" ColorBold = "\033[1m" ColorDim = "\033[2m" ColorRed = "\033[31m" ColorGreen = "\033[32m" ColorYellow = "\033[33m" ColorBlue = "\033[34m" ColorMagenta = "\033[35m" ColorCyan = "\033[36m" ColorWhite = "\033[37m" ) func Banner(version, username, role, hostname string) string { var sb strings.Builder sb.WriteString("\n") sb.WriteString(ColorCyan + ColorBold) sb.WriteString(" ____ _ _____ _ _ \n") sb.WriteString(" | _ \\ ___| |_|_ _(_) | __\n") sb.WriteString(" | | | |/ _ \\ '_ \\| | | | |/ /\n") sb.WriteString(" | |_| | __/ |_) | | | | < \n") sb.WriteString(" |____/ \\___|_.__/|_| |_|_|\\_\\\n") sb.WriteString(ColorReset) sb.WriteString(ColorBold + " DebTik Network Appliance Controller" + ColorReset + "\n") sb.WriteString(fmt.Sprintf(ColorDim+" Appliance Hostname : %s%s\n", hostname, ColorReset)) sb.WriteString(fmt.Sprintf(ColorDim+" Authenticated User : %s%s%s (Role: %s%s%s)\n", ColorGreen, username, ColorDim, ColorYellow, strings.ToUpper(role), ColorDim)) sb.WriteString(ColorDim + " Type 'help' or '?' for available commands.\n" + ColorReset) sb.WriteString("\n") return sb.String() } // TableWriter formats aligned text tables with custom columns type TableWriter struct { headers []string rows [][]string } func NewTable(headers ...string) *TableWriter { return &TableWriter{ headers: headers, rows: make([][]string, 0), } } func (t *TableWriter) AddRow(cols ...string) { t.rows = append(t.rows, cols) } func (t *TableWriter) String() string { return t.Render() } func (t *TableWriter) Render() string { if len(t.headers) == 0 { return "" } colWidths := make([]int, len(t.headers)) for i, h := range t.headers { colWidths[i] = len(h) } for _, row := range t.rows { for i, cell := range row { if i < len(colWidths) { cleanLen := len(stripANSI(cell)) if cleanLen > colWidths[i] { colWidths[i] = cleanLen } } } } var sb strings.Builder // Render Header sb.WriteString(ColorCyan + ColorBold) for i, h := range t.headers { pad := colWidths[i] - len(h) sb.WriteString(fmt.Sprintf(" %s%s ", h, strings.Repeat(" ", max(0, pad)))) } sb.WriteString(ColorReset + "\n") // Render separator sb.WriteString(ColorDim) for i := range t.headers { sb.WriteString(fmt.Sprintf(" %s ", strings.Repeat("-", colWidths[i]))) } sb.WriteString(ColorReset + "\n") // Render Rows for _, row := range t.rows { for i := range t.headers { cell := "" if i < len(row) { cell = row[i] } cleanLen := len(stripANSI(cell)) pad := colWidths[i] - cleanLen sb.WriteString(fmt.Sprintf(" %s%s ", cell, strings.Repeat(" ", max(0, pad)))) } sb.WriteString("\n") } return sb.String() } func stripANSI(str string) string { var clean strings.Builder inEsc := false for _, r := range str { if r == 0x1b { // ESC inEsc = true continue } if inEsc { if (r >= 'a' && r <= 'z') || (r >= 'A' && r <= 'Z') { inEsc = false } continue } clean.WriteRune(r) } return clean.String() } func max(a, b int) int { if a > b { return a } return b }