// meta4ra -- Metalink 4.0 utilities
// Copyright (C) 2021-2026 Sergey Matveev <stargrave@stargrave.org>
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3 of the License.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

package internal

import (
	"crypto/sha256"
	"crypto/sha3"
	"crypto/sha512"
	"encoding/hex"
	"hash"
	"io"
)

const BuiltinCmd = "builtin"

var (
	BuiltinHashers map[string]func() hash.Hash = map[string]func() hash.Hash{
		"sha-256":  sha256.New,
		"sha-512":  sha512.New,
		"shake128": func() hash.Hash { return shake{l: 32, h: sha3.NewSHAKE128()} },
		"shake256": func() hash.Hash { return shake{l: 64, h: sha3.NewSHAKE256()} },
	}
	HashersDefault = `shake128 builtin
shake256 builtin
sha-512 builtin
sha-256 builtin
`
)

type BuiltinHasher struct {
	h        hash.Hash
	finished bool
}

func (h *BuiltinHasher) Write(p []byte) (int, error) {
	return h.h.Write(p)
}

func (h *BuiltinHasher) Read(p []byte) (int, error) {
	if h.finished {
		return 0, io.EOF
	}
	if len(p) < 2*h.h.Size() {
		panic("too small buffer for BuiltinHasher.h.Sum()")
	}
	hex.Encode(p, h.h.Sum(nil))
	h.finished = true
	return hex.EncodedLen(h.h.Size()), nil
}

func (h *BuiltinHasher) Close() error {
	return nil
}
