// Copyright 2025 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

package cgroup

import (
	"internal/bytealg"
)

// stringError is a trival implementation of error, equivalent to errors.New,
// which cannot be imported from a runtime package.
type stringError string

func (e stringError) Error() string {
	return string(e)
}

// All errors are explicit converted to type error in global initialization to
// ensure that the linker allocates a static interface value. This is necessary
// because these errors may be used before the allocator is available.

var (
	// The entire line did not fit into the scratch buffer.
	errIncompleteLine error = stringError("incomplete line")

	// A system call failed.
	errSyscallFailed error = stringError("syscall failed")

	// Reached EOF.
	errEOF error = stringError("end of file")
)

// lineReader reads line-by-line using only a single fixed scratch buffer.
//
// When a single line is too long for the scratch buffer, the remainder of the
// line will be skipped.
type lineReader struct {
	read    func(fd int, b []byte) (int, uintptr)
	fd      int
	scratch []byte

	n       int // bytes of scratch in use.
	newline int // index of the first newline in scratch.

	eof bool // read reached EOF.
}

// newLineReader returns a lineReader which reads lines from fd.
//
// fd is the file descriptor to read from.
//
// scratch is the scratch buffer to read into. Note that len(scratch) is the
// longest line that can be read. Lines longer than len(scratch) will have the
// remainder of the line skipped. See next for more details.
//
// read is the function used to read more bytes from fd. This is usually
// internal/runtime/syscall/linux.Read. Note that this follows syscall semantics (not
// io.Reader), so EOF is indicated with n=0, errno=0.
func newLineReader(fd int, scratch []byte, read func(fd int, b []byte) (n int, errno uintptr)) *lineReader {
	return &lineReader{
		read:    read,
		fd:      fd,
		scratch: scratch,
		n:       0,
		newline: -1,
	}
}

// next advances to the next line.
//
// May return errIncompleteLine if the scratch buffer is too small to hold the
// entire line, in which case [r.line] will return the beginning of the line. A
// subsequent call to next will skip the remainder of the incomplete line.
//
// N.B. this behavior is important for /proc/self/mountinfo. Some lines
// (mounts), such as overlayfs, may be extremely long due to long super-block
// options, but we don't care about those. The mount type will appear early in
// the line.
//
// Returns errEOF when there are no more lines.
func (r *lineReader) next() error {
	// Three cases:
	//
	// 1. First call, no data read.
	// 2. Previous call had a complete line. Drop it and look for the end
	//    of the next line.
	// 3. Previous call had an incomplete line. Find the end of that line
	//    (start of the next line), and the end of the next line.

	prevComplete := r.newline >= 0
	firstCall := r.n == 0

	for {
		if prevComplete {
			// Drop the previous line.
			copy(r.scratch, r.scratch[r.newline+1:r.n])
			r.n -= r.newline + 1

			r.newline = bytealg.IndexByte(r.scratch[:r.n], '\n')
			if r.newline >= 0 {
				// We have another line already in scratch. Done.
				return nil
			}
		}

		// No newline available.

		if !prevComplete {
			// If the previous line was incomplete, we are
			// searching for the end of that line and have no need
			// for any buffered data.
			r.n = 0
		}

		n, errno := r.read(r.fd, r.scratch[r.n:len(r.scratch)])
		if errno != 0 {
			return errSyscallFailed
		}
		r.n += n

		if r.n == 0 {
			// Nothing left.
			//
			// N.B. we can't immediately return EOF when read
			// returns 0 as we may still need to return an
			// incomplete line.
			return errEOF
		}

		r.newline = bytealg.IndexByte(r.scratch[:r.n], '\n')
		if prevComplete || firstCall {
			// Already have the start of the line, just need to find the end.

			if r.newline < 0 {
				// We filled the entire buffer or hit EOF, but
				// still no newline.
				return errIncompleteLine
			}

			// Found the end of the line. Done.
			return nil
		} else {
			// Don't have the start of the line. We are currently
			// looking for the end of the previous line.

			if r.newline < 0 {
				// Not there yet.
				if n == 0 {
					// No more to read.
					return errEOF
				}
				continue
			}

			// Found the end of the previous line. The next
			// iteration will drop the remainder of the previous
			// line and look for the next line.
			prevComplete = true
		}
	}
}

// line returns a view of the current line, excluding the trailing newline.
//
// If [r.next] returned errIncompleteLine, then this returns only the beginning
// of the line.
//
// Preconditions: [r.next] is called prior to the first call to line.
//
// Postconditions: The caller must not keep a reference to the returned slice.
func (r *lineReader) line() []byte {
	if r.newline < 0 {
		// Incomplete line
		return r.scratch[:r.n]
	}
	// Complete line.
	return r.scratch[:r.newline]
}
