/*
Copyright 2023 The Kubernetes Authors.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package util

import (
	"bytes"
	"fmt"
)

// LineBuffer is an interface for writing lines of input to a bytes.Buffer
type LineBuffer interface {
	// Write takes a list of arguments, each a string or []string, joins all the
	// individual strings with spaces, terminates with newline, and writes them to the
	// buffer. Any other argument type will panic.
	Write(args ...interface{})

	// WriteBytes writes bytes to the buffer, and terminates with newline.
	WriteBytes(bytes []byte)

	// Reset clears the buffer
	Reset()

	// Bytes returns the contents of the buffer as a []byte
	Bytes() []byte

	// String returns the contents of the buffer as a string
	String() string

	// Lines returns the number of lines in the buffer. Note that more precisely, this
	// returns the number of times Write() or WriteBytes() was called; it assumes that
	// you never wrote any newlines to the buffer yourself.
	Lines() int
}

type realLineBuffer struct {
	b     bytes.Buffer
	lines int
}

// NewLineBuffer returns a new "real" LineBuffer
func NewLineBuffer() LineBuffer {
	return &realLineBuffer{}
}

// Write is part of LineBuffer
func (buf *realLineBuffer) Write(args ...interface{}) {
	for i, arg := range args {
		if i > 0 {
			buf.b.WriteByte(' ')
		}
		switch x := arg.(type) {
		case string:
			buf.b.WriteString(x)
		case []string:
			for j, s := range x {
				if j > 0 {
					buf.b.WriteByte(' ')
				}
				buf.b.WriteString(s)
			}
		default:
			panic(fmt.Sprintf("unknown argument type: %T", x))
		}
	}
	buf.b.WriteByte('\n')
	buf.lines++
}

// WriteBytes is part of LineBuffer
func (buf *realLineBuffer) WriteBytes(bytes []byte) {
	buf.b.Write(bytes)
	buf.b.WriteByte('\n')
	buf.lines++
}

// Reset is part of LineBuffer
func (buf *realLineBuffer) Reset() {
	buf.b.Reset()
	buf.lines = 0
}

// Bytes is part of LineBuffer
func (buf *realLineBuffer) Bytes() []byte {
	return buf.b.Bytes()
}

// String is part of LineBuffer
func (buf *realLineBuffer) String() string {
	return buf.b.String()
}

// Lines is part of LineBuffer
func (buf *realLineBuffer) Lines() int {
	return buf.lines
}

type discardLineBuffer struct {
	lines int
}

// NewDiscardLineBuffer returns a dummy LineBuffer that counts the number of writes but
// throws away the data. (This is used for iptables proxy partial syncs, to keep track of
// how many rules we managed to avoid having to sync.)
func NewDiscardLineBuffer() LineBuffer {
	return &discardLineBuffer{}
}

// Write is part of LineBuffer
func (buf *discardLineBuffer) Write(args ...interface{}) {
	buf.lines++
}

// WriteBytes is part of LineBuffer
func (buf *discardLineBuffer) WriteBytes(bytes []byte) {
	buf.lines++
}

// Reset is part of LineBuffer
func (buf *discardLineBuffer) Reset() {
	buf.lines = 0
}

// Bytes is part of LineBuffer
func (buf *discardLineBuffer) Bytes() []byte {
	return []byte{}
}

// String is part of LineBuffer
func (buf *discardLineBuffer) String() string {
	return ""
}

// Lines is part of LineBuffer
func (buf *discardLineBuffer) Lines() int {
	return buf.lines
}
