// Command gentable generates the canonical FastCDC Gear tables.
package main

import (
	"bytes"
	"crypto/md5"
	"crypto/sha256"
	"encoding/binary"
	"fmt"
	"go/format"
	"os"
)

func main() {
	var gear [256]uint64
	var encoded [256 * 8]byte
	for i := range gear {
		seed := bytes.Repeat([]byte{byte(i)}, 64)
		digest := md5.Sum(seed)
		gear[i] = binary.BigEndian.Uint64(digest[:8])
		binary.BigEndian.PutUint64(encoded[i*8:], gear[i])
	}

	var out bytes.Buffer
	fmt.Fprintln(&out, "// Code generated by internal/gentable; DO NOT EDIT.")
	fmt.Fprintf(&out, "// Gear table SHA-256 (big-endian uint64s): %x\n\n", sha256.Sum256(encoded[:]))
	fmt.Fprintln(&out, "package fastcdc")
	writeTable(&out, gear)

	formatted, err := format.Source(out.Bytes())
	if err != nil {
		panic(err)
	}
	if err := os.WriteFile("gear_gen.go", formatted, 0o644); err != nil {
		panic(err)
	}
}

func writeTable(out *bytes.Buffer, table [256]uint64) {
	fmt.Fprintln(out, "\nvar gear = [256]uint64{")
	for i, value := range table {
		fmt.Fprintf(out, "0x%016x,", value)
		if i%4 == 3 {
			fmt.Fprintln(out)
		}
	}
	fmt.Fprintln(out, "}")
}
