// Copyright 2024 PingCAP, Inc. Licensed under Apache-2.0.

package utils

import (
	"bufio"
	"fmt"
)

const maxLineSize = 1073741824

// readLine is a general utility function for reading a complete line
// from bufio.Reader, the single-line size limit is specified by maxLineSize.
func ReadLine(reader *bufio.Reader) ([]byte, error) {
	var resByte []byte
	lineByte, isPrefix, err := reader.ReadLine()
	if isPrefix {
		// Need to read more data.
		resByte = make([]byte, len(lineByte), len(lineByte)*2)
	} else {
		resByte = make([]byte, len(lineByte))
	}
	// Use copy here to avoid shallow copy problem.
	copy(resByte, lineByte)
	if err != nil {
		return resByte, err
	}
	var tempLine []byte
	for isPrefix {
		tempLine, isPrefix, err = reader.ReadLine()
		if len(tempLine) > 0 {
			// nolint:makezero
			resByte = append(resByte, tempLine...)
		}
		// Use the max value of max_allowed_packet to check the single line length.
		if len(resByte) > maxLineSize {
			return resByte, fmt.Errorf("single line length exceeds limit: %v", maxLineSize)
		}
		if err != nil {
			return resByte, err
		}
	}
	return resByte, err
}
