diff --git a/go.mod b/go.mod index e4710c6..791020c 100644 --- a/go.mod +++ b/go.mod @@ -1,3 +1,9 @@ module cimeyclust.com/steel go 1.21 + +require ( + github.com/gizak/termui v3.1.0+incompatible // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/nsf/termbox-go v1.1.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..c0279e1 --- /dev/null +++ b/go.sum @@ -0,0 +1,6 @@ +github.com/gizak/termui v3.1.0+incompatible h1:N3CFm+j087lanTxPpHOmQs0uS3s5I9TxoAFy6DqPqv8= +github.com/gizak/termui v3.1.0+incompatible/go.mod h1:PkJoWUt/zacQKysNfQtcw1RW+eK2SxkieVBtl+4ovLA= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= +github.com/nsf/termbox-go v1.1.1 h1:nksUPLCb73Q++DwbYUBEglYBRPZyoXJdrj5L+TkjyZY= +github.com/nsf/termbox-go v1.1.1/go.mod h1:T0cTdVuOwf7pHQNtfhnEbzHbcNyCEcVU4YPpouCbVxo= diff --git a/pkg/cmd/console.go b/pkg/cmd/console.go index 3c4a209..4141d8d 100644 --- a/pkg/cmd/console.go +++ b/pkg/cmd/console.go @@ -6,32 +6,81 @@ import ( "os" "strings" "sync" + "time" ) +type Log struct { + // Level enum of "info", "warning", "error" + Level string + + // Message to be logged + Message string + + // Time of the log + Time string + + // Source of the log + Source string +} + +type LoggerQueue struct { + queue chan Log +} + +var Logger = &LoggerQueue{ + queue: make(chan Log, 100), +} + +func (l *LoggerQueue) log(level string, message string, source string) { + l.queue <- Log{ + Level: level, + Message: message, + Time: time.Now().Format("2006/01/02 15:04:05"), + Source: source, + } +} + +func (l *LoggerQueue) Info(message string) { + l.log("INFO", message, "") +} + +func (l *LoggerQueue) Warning(message string) { + l.log("WARNING", message, "") +} + +func (l *LoggerQueue) Error(message string) { + l.log("ERROR", message, "") +} + +func (l *LoggerQueue) processLogs() { + for logEntry := range l.queue { + // Move cursor up and clear line + fmt.Printf("%s [%s]: %s\n", logEntry.Time, logEntry.Level, logEntry.Message) + } +} + func Start(wg *sync.WaitGroup, stopChan chan struct{}) { defer wg.Done() + go Logger.processLogs() + reader := bufio.NewReader(os.Stdin) for { fmt.Print("> ") input, err := reader.ReadString('\n') if err != nil { - _, err := fmt.Fprintf(os.Stderr, "Error while reading input: %v", err) - if err != nil { - return - } - close(stopChan) - return + Logger.Error(fmt.Sprintf("Error while reading input: %v", err)) + continue } input = strings.TrimSpace(input) switch input { case "stop": - fmt.Println("Received stop command.") + Logger.Info("Received stop command.") close(stopChan) return default: - fmt.Println("Unknown command:", input) + Logger.Info(fmt.Sprintf("Unknown command: %s", input)) } } } diff --git a/pkg/net/network.go b/pkg/net/network.go index 25a12d1..a0b871b 100644 --- a/pkg/net/network.go +++ b/pkg/net/network.go @@ -1,10 +1,11 @@ package net import ( + "cimeyclust.com/steel/pkg/cmd" "fmt" "net" - "os" "sync" + "time" ) // Start Starts the TCP server on the specified address. @@ -14,11 +15,7 @@ func Start(addr string, stopChan <-chan struct{}, wg *sync.WaitGroup) { // Start listening on the specified address listener, err := net.Listen("tcp", addr) if err != nil { - _, err := fmt.Fprintf(os.Stderr, "Error starting TCP server: %v", err) - if err != nil { - return - } - return + cmd.Logger.Error("Error starting TCP server: %v") } // Close the listener when the application closes. @@ -29,7 +26,21 @@ func Start(addr string, stopChan <-chan struct{}, wg *sync.WaitGroup) { } }(listener) - fmt.Printf("TCP server listening on %s\n", addr) + // slog.Info(fmt.Sprintf("Listening on %s", addr)) + cmd.Logger.Info(fmt.Sprintf("Listening on %s", addr)) + + go func() { + for { + // Print test every second + select { + case <-stopChan: + return // Safe exit if stop has been signalled + default: + cmd.Logger.Info("Test") + } + time.Sleep(1 * time.Second) + } + }() // Listen for an incoming connection in a goroutine. go func() { @@ -40,7 +51,7 @@ func Start(addr string, stopChan <-chan struct{}, wg *sync.WaitGroup) { case <-stopChan: return // Safe exit if stop has been signalled default: - fmt.Fprintf(os.Stderr, "Error accepting connection: %v", err) + cmd.Logger.Error(fmt.Sprintf("Error while accepting conn: %v", err)) } continue } @@ -65,7 +76,7 @@ func handleRequest(conn net.Conn) { // Read the incoming connection into the buffer. _, err := conn.Read(buf) if err != nil { - fmt.Fprintf(os.Stderr, "Error reading: %v", err) + cmd.Logger.Error(fmt.Sprintf("Error reading: %v", err)) return } diff --git a/pkg/utils/queue.go b/pkg/utils/queue.go new file mode 100644 index 0000000..1ea6cea --- /dev/null +++ b/pkg/utils/queue.go @@ -0,0 +1,53 @@ +package utils + +// Queue implementation + +type Node struct { + Value interface{} + Next *Node +} + +type Queue struct { + Head *Node + Tail *Node +} + +func (q *Queue) Enqueue(value interface{}) { + node := &Node{Value: value} + + if q.Head == nil { + q.Head = node + q.Tail = node + return + } + + q.Tail.Next = node + q.Tail = node +} + +func (q *Queue) Dequeue() interface{} { + if q.Head == nil { + return nil + } + + node := q.Head + q.Head = node.Next + + if q.Head == nil { + q.Tail = nil + } + + return node.Value +} + +func (q *Queue) Peek() interface{} { + if q.Head == nil { + return nil + } + + return q.Head.Value +} + +func (q *Queue) IsEmpty() bool { + return q.Head == nil +} diff --git a/steel.go b/steel.go index a8f8b9c..5daecb2 100644 --- a/steel.go +++ b/steel.go @@ -19,6 +19,8 @@ func main() { wg.Add(1) go net.Start("localhost:8080", stopChan, &wg) + cmd.Logger.Info("Started") + // Wait for all components to finish wg.Wait() }