package adapter

import "fmt"

type truncateAdapter struct {
	sourceDim int
	targetDim int
	truncMode TruncateMode
	padMode   PadMode
}

func (a *truncateAdapter) SourceDim() int { return a.sourceDim }
func (a *truncateAdapter) TargetDim() int { return a.targetDim }

func (a *truncateAdapter) Adapt(vec []float32) ([]float32, error) {
	if len(vec) != a.sourceDim {
		return nil, fmt.Errorf("truncate adapt: %w: got %d, want %d", ErrDimMismatch, len(vec), a.sourceDim)
	}

	out := make([]float32, a.targetDim)

	if a.targetDim <= a.sourceDim {
		// Downscale: truncate
		switch a.truncMode {
		case TruncateFromEnd:
			copy(out, vec[:a.targetDim])
		case TruncateFromStart:
			copy(out, vec[a.sourceDim-a.targetDim:])
		}
	} else {
		// Upscale: zero-pad
		switch a.padMode {
		case PadAtEnd:
			copy(out, vec)
		case PadAtStart:
			copy(out[a.targetDim-a.sourceDim:], vec)
		}
	}

	return L2Norm(out), nil
}
