package idgen

import (
	"crypto/rand"
	"encoding/base32"
	"sync"
	"time"
)

// Creates a new, random token.
func NewToken() string {
	buf := make([]byte, 20)
	_, err := rand.Read(buf)
	if err != nil {
		panic(err)
	}
	return base32.StdEncoding.EncodeToString(buf)
}

var (
	lock       sync.Mutex
	ts         int64 = time.Now().Unix()
	counter    int64 = 1
	counterMax int64 = 1 << 20
)

// NextID can generate ~1M ints per second for a given nodeID.
//
// nodeID must be less than 64.
func NextID(nodeID int64) int64 {
	lock.Lock()
	defer lock.Unlock()

	tt := time.Now().Unix()
	if tt > ts {
		ts = tt
		counter = 1
	} else {
		counter++
		if counter == counterMax {
			panic("Too many IDs.")
		}
	}

	return (ts << 26) + (nodeID << 20) + counter
}

func SplitID(id int64) (unixTime, nodeID, counter int64) {
	counter = id & (0x00000000000FFFFF)
	nodeID = (id >> 20) & (0x000000000000003F)
	unixTime = id >> 26
	return
}