package io

import (
	
	
)

// RingBuffer struct satisfies io.ReadWrite interface.
//
// ReadBuffer is a revolving buffer data structure, which can be used to store snapshots of data in a
// revolving window.
type RingBuffer struct {
	slice []byte
	start int
	end   int
	size  int
}

// NewRingBuffer method takes in a byte slice as an input and returns a RingBuffer.
func ( []byte) *RingBuffer {
	 := RingBuffer{
		slice: ,
	}
	return &
}

// Write method inserts the elements in a byte slice, and returns the number of bytes written along with any error.
func ( *RingBuffer) ( []byte) (int, error) {
	for ,  := range  {
		// check if end points to invalid index, we need to circle back
		if .end == len(.slice) {
			.end = 0
		}
		// check if start points to invalid index, we need to circle back
		if .start == len(.slice) {
			.start = 0
		}
		// if ring buffer is filled, increment the start index
		if .size == len(.slice) {
			.size--
			.start++
		}

		.slice[.end] = 
		.end++
		.size++
	}
	return len(), nil
}

// Read copies the data on the ring buffer into the byte slice provided to the method.
// Returns the read count along with any error encountered while reading.
func ( *RingBuffer) ( []byte) (int, error) {
	// readCount keeps track of the number of bytes read
	var  int
	for  := 0;  < len(); ++ {
		// if ring buffer is empty or completely read
		// return EOF error.
		if .size == 0 {
			return , io.EOF
		}

		if .start == len(.slice) {
			.start = 0
		}

		[] = .slice[.start]
		++
		// increment the start pointer for ring buffer
		.start++
		// decrement the size of ring buffer
		.size--
	}
	return , nil
}

// Len returns the number of unread bytes in the buffer.
func ( *RingBuffer) () int {
	return .size
}

// Bytes returns a copy of the RingBuffer's bytes.
func ( RingBuffer) () []byte {
	var  bytes.Buffer
	io.Copy(&, &)
	return .Bytes()
}

// Reset resets the ring buffer.
func ( *RingBuffer) () {
	* = RingBuffer{
		slice: .slice,
	}
}