package padding

import "fmt"

type P7Padding struct {
}

func (P7Padding) Pad(src []byte, blockSize int) (dst []byte) {
	if blockSize < MIN_BLOCK_SIZE || blockSize > MAX_BLOCK_SIZE {
		panic("blocksize error")
	}
	// if blocksize == 2^n, then paddingsize = -len(src) & (blocksize - 1)
	paddingSize := byte(blockSize - (len(src) % blockSize))
	for i := 0; i < int(paddingSize); i++ {
		src = append(src, paddingSize)
	}
	return src
}

func (P7Padding) Unpad(src []byte, blockSize int) (dst []byte, err error) {
	if blockSize < MIN_BLOCK_SIZE || blockSize > MAX_BLOCK_SIZE {
		panic("blocksize error")
	}

	if len(src) == 0 {
		return src, nil
	}
	paddingSize := int(uint(src[len(src)-1]))

	if paddingSize > len(src) || paddingSize == 0 {
		return src, fmt.Errorf("unpadding error")
	}

	for i := len(src) - paddingSize; i < len(src)-1; i++ {
		if int(src[i]) != paddingSize {
			return src, fmt.Errorf("unpadding error")
		}
	}

	return src[:len(src)-paddingSize], nil
}
