package main

// RFC 6238 TOTP (SHA1, 30s, 6 digits) for Bitwarden 2FA provider 0.

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base32"
	"encoding/binary"
	"fmt"
	"strings"
	"time"
)

func totpNow(secretB32 string, at time.Time) (string, error) {
	secret := strings.ToUpper(strings.ReplaceAll(strings.ReplaceAll(secretB32, " ", ""), "-", ""))
	pad := len(secret) % 8
	if pad != 0 {
		secret += strings.Repeat("=", 8-pad)
	}
	key, err := base32.StdEncoding.DecodeString(secret)
	if err != nil {
		return "", err
	}
	counter := uint64(at.Unix()) / 30
	var ctr [8]byte
	binary.BigEndian.PutUint64(ctr[:], counter)
	h := hmac.New(sha1.New, key)
	h.Write(ctr[:])
	sum := h.Sum(nil)
	off := sum[len(sum)-1] & 0x0f
	code := (binary.BigEndian.Uint32(sum[off:off+4]) & 0x7fffffff) % 1000000
	return fmt.Sprintf("%06d", code), nil
}
