package proc

import (
	"fmt"
	"io"
	"sync"
)

// prefixWriter prefixes each line written through it with "[name] ".
// It is safe for concurrent use.
type prefixWriter struct {
	dst     io.Writer
	prefix  string
	mu      sync.Mutex
	lineBuf []byte
}

func newPrefixWriter(dst io.Writer, name string) *prefixWriter {
	return &prefixWriter{dst: dst, prefix: name}
}

func (w *prefixWriter) Write(p []byte) (int, error) {
	w.mu.Lock()
	defer w.mu.Unlock()
	for _, b := range p {
		if b == '\n' {
			w.lineBuf = append(w.lineBuf, b)
			if _, err := fmt.Fprintf(w.dst, "[%s] %s", w.prefix, w.lineBuf); err != nil {
				return len(p), err
			}
			w.lineBuf = w.lineBuf[:0]
			continue
		}
		w.lineBuf = append(w.lineBuf, b)
	}
	return len(p), nil
}

// Flush writes any buffered partial line without a trailing newline.
func (w *prefixWriter) Flush() {
	w.mu.Lock()
	defer w.mu.Unlock()
	if len(w.lineBuf) > 0 {
		_, _ = fmt.Fprintf(w.dst, "[%s] %s\n", w.prefix, w.lineBuf)
		w.lineBuf = w.lineBuf[:0]
	}
}
