//nolint:unused
package data

import (
	"github.com/cheekybits/genny/generic"
)

type gen generic.Type

type genVector []gen

func newgenVector(n int) *genVector {
	v := genVector(make([]gen, n))
	return &v
}

func newgenVectorWithValues(s []gen) *genVector {
	v := make([]gen, len(s))
	copy(v, s)
	return (*genVector)(&v)
}

func (v *genVector) Set(idx int, i interface{}) {
	(*v)[idx] = i.(gen)
}

func (v *genVector) SetConcrete(idx int, i interface{}) {
	v.Set(idx, i)
}

func (v *genVector) Append(i interface{}) {
	*v = append(*v, i.(gen))
}

func (v *genVector) NilAt(i int) bool {
	return false
}

func (v *genVector) At(i int) interface{} {
	return (*v)[i]
}

func (v *genVector) PointerAt(i int) interface{} {
	return &(*v)[i]
}

func (v *genVector) Len() int {
	return len(*v)
}

func (v *genVector) Cap() int {
	return cap(*v)
}

func (v *genVector) CopyAt(i int) interface{} {
	var g gen //nolint:staticcheck // S1021: generated code pattern
	g = (*v)[i]
	return g
}

func (v *genVector) ConcreteAt(i int) (interface{}, bool) {
	return v.At(i), true
}

func (v *genVector) Type() FieldType {
	return vectorFieldType(v)
}

func (v *genVector) Extend(i int) {
	*v = append(*v, make([]gen, i)...)
}

// Grow reserves capacity for at least n additional elements without changing
// the vector's length. It is a no-op if the existing capacity already fits.
func (v *genVector) Grow(n int) {
	if n <= 0 || cap(*v)-len(*v) >= n {
		return
	}
	grown := make([]gen, len(*v), len(*v)+n)
	copy(grown, *v)
	*v = grown
}

// set the length to zero, but keep the same capacity
func (v *genVector) Clear() {
	*v = (*v)[:0]
}

func (v *genVector) Insert(i int, val interface{}) {
	switch {
	case i < v.Len():
		v.Extend(1)
		copy((*v)[i+1:], (*v)[i:])
		v.Set(i, val)
	case i == v.Len():
		v.Append(val)
	case i > v.Len():
		panic("Invalid index; vector length should be greater or equal to that index")
	}
}

func (v *genVector) Delete(i int) {
	*v = append((*v)[:i], (*v)[i+1:]...)
}
