// Copyright (C) 2023 Marius Schellenberger

package core

import (
	"bytes"

	"github.com/hashicorp/vault/shamir"
)

type Type int

const (
	Plain Type = iota
	Shamir
	Xor
)

func (t Type) String() string {
	switch t {
	case Shamir:
		return "shamir"
	case Xor:
		return "xor"
	}
	return "plain"
}

func (t Type) Decode(src []byte) ([]byte, error) {
	switch t {
	case Shamir:
		p1, p2 := split(src)
		return shamir.Combine([][]byte{p1, p2})
	case Xor:
		return xor(src), nil
	}
	return src, nil
}

func split(src []byte) (p1, p2 []byte) {
	plen := len(src) / 2
	return src[0:plen], src[plen:]
}

func xor(src []byte) []byte {
	p1, p2 := split(src)
	for i := 0; i < len(p1); i++ {
		p1[i] ^= p2[i]
	}
	return p1
}

func (t Type) Encode(src []byte) ([]byte, error) {
	switch t {
	case Shamir:
		parts, err := shamir.Split(src, 2, 2)
		if err != nil {
			return nil, err
		}
		return bytes.Join(parts, nil), nil
	}
	return src, nil
}

func TypeFromString(t string) Type {
	switch t {
	case "shamir":
		return Shamir
	case "xor":
		return Xor
	}
	return Plain
}
