// Copyright 2016 The Netstack 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 buffer provides the implementation of a buffer view.
package buffer

// View is a slice of a buffer, with convenience methods.
type View []byte

// NewView allocates a new buffer and returns an initialized view that covers
// the whole buffer.
func NewView(size int) View {
	return make(View, size)
}

// TrimFront removes the first "count" bytes from the visible section of the
// buffer.
func (v *View) TrimFront(count int) {
	*v = (*v)[count:]
}

// CapLength irreversibly reduces the length of the visible section of the
// buffer to the value specified.
func (v *View) CapLength(length int) {
	// We also set the slice cap because if we don't, one would be able to
	// expand the view back to include the region just excluded. We want to
	// prevent that to avoid potential data leak if we have uninitialized
	// data in excluded region.
	*v = (*v)[:length:length]
}

// ToVectorisedView transforms a View in a VectorisedView from an
// already-allocated slice of View.
func (v *View) ToVectorisedView(views [1]View) VectorisedView {
	views[0] = *v
	return NewVectorisedView(len(*v), views[:])
}

// VectorisedView is a vectorised version of View using non contigous memory.
// It supports all the convenience methods supported by View.
type VectorisedView struct {
	views []View
	size  int
}

// NewVectorisedView creates a new vectorised view from an already-allocated slice
// of View and sets its size.
func NewVectorisedView(size int, views []View) VectorisedView {
	return VectorisedView{views: views, size: size}
}

// TrimFront removes the first "count" bytes of the vectorised view.
func (vv *VectorisedView) TrimFront(count int) {
	for count > 0 && len(vv.views) > 0 {
		if count < len(vv.views[0]) {
			vv.size -= count
			vv.views[0].TrimFront(count)
			return
		}
		count -= len(vv.views[0])
		vv.RemoveFirst()
	}
}

// CapLength irreversibly reduces the length of the vectorised view.
func (vv *VectorisedView) CapLength(length int) {
	if length < 0 {
		length = 0
	}
	if vv.size < length {
		return
	}
	vv.size = length
	for i := range vv.views {
		v := &vv.views[i]
		if len(*v) >= length {
			if length == 0 {
				vv.views = vv.views[:i]
			} else {
				v.CapLength(length)
				vv.views = vv.views[:i+1]
			}
			return
		}
		length -= len(*v)
	}
}

// Clone returns a clone of this VectorisedView.
// If the buffer argument is large enough to contain all the Views of this VectorisedView,
// the method will avoid allocations and use the buffer to store the Views of the clone.
func (vv *VectorisedView) Clone(buffer []View) VectorisedView {
	var views []View
	if len(buffer) >= len(vv.views) {
		views = buffer[:len(vv.views)]
	} else {
		views = make([]View, len(vv.views))
	}
	for i, v := range vv.views {
		views[i] = v
	}
	return VectorisedView{views: views, size: vv.size}
}

// First returns the first view of the vectorised view.
// It panics if the vectorised view is empty.
func (vv *VectorisedView) First() View {
	if len(vv.views) == 0 {
		panic("vview is empty")
	}
	return vv.views[0]
}

// RemoveFirst removes the first view of the vectorised view.
func (vv *VectorisedView) RemoveFirst() {
	if len(vv.views) == 0 {
		return
	}
	vv.size -= len(vv.views[0])
	vv.views = vv.views[1:]
}

// SetSize unsafely sets the size of the VectorisedView.
func (vv *VectorisedView) SetSize(size int) {
	vv.size = size
}

// SetViews unsafely sets the views of the VectorisedView.
func (vv *VectorisedView) SetViews(views []View) {
	vv.views = views
}

// Size returns the size in bytes of the entire content stored in the vectorised view.
func (vv *VectorisedView) Size() int {
	return vv.size
}

// ToView returns the a single view containing the content of the vectorised view.
func (vv *VectorisedView) ToView() View {
	v := make([]byte, vv.size)
	u := v
	for i := range vv.views {
		n := copy(u, vv.views[i])
		u = u[n:]
	}
	return v
}

// Views returns the slice containing the all views.
func (vv *VectorisedView) Views() []View {
	return vv.views
}

// ByteSlice returns a slice containing the all views as a []byte.
func (vv *VectorisedView) ByteSlice() [][]byte {
	s := make([][]byte, len(vv.views))
	for i := range vv.views {
		s[i] = []byte(vv.views[i])
	}
	return s
}

// copy returns a deep-copy of the vectorised view.
// It is an expensive method that should be used only in tests.
func (vv *VectorisedView) copy() *VectorisedView {
	uu := &VectorisedView{
		views: make([]View, len(vv.views)),
		size:  vv.size,
	}
	for i, v := range vv.views {
		uu.views[i] = make(View, len(v))
		copy(uu.views[i], v)
	}
	return uu
}
