package main

import (
	"errors"
	"fmt"
	"sync"
)

type Resource struct {
	mu    sync.Mutex
	Fence uint64
	Value string
}

func (r *Resource) Write(token uint64, value string) error {
	r.mu.Lock()
	defer r.mu.Unlock()
	if token < r.Fence {
		return errors.New("stale fence")
	}
	r.Fence = token
	r.Value = value
	return nil
}

type Snowflake struct {
	last int64
	seq  uint64
	node uint64
}

func (s *Snowflake) Next(ms int64) (uint64, error) {
	if s.node >= 1<<10 || ms < 0 || ms >= 1<<41 {
		return 0, errors.New("out of range")
	}
	if ms < s.last {
		return 0, errors.New("clock rollback")
	}
	if ms == s.last {
		if s.seq == 4095 {
			return 0, errors.New("sequence exhausted")
		}
		s.seq++
	} else {
		s.last = ms
		s.seq = 0
	}
	return uint64(ms)<<22 | s.node<<12 | s.seq, nil
}

type JobLedger struct {
	mu      sync.Mutex
	done    map[string]bool
	Effects int
}

func (j *JobLedger) Run(key string) bool {
	j.mu.Lock()
	defer j.mu.Unlock()
	if j.done[key] {
		return false
	}
	j.Effects++
	j.done[key] = true
	return true
}
func main() {
	r := Resource{}
	fmt.Println("new owner:", r.Write(42, "B"))
	fmt.Println("expired owner:", r.Write(41, "A"), "value:", r.Value)
	s := Snowflake{last: -1, node: 3}
	a, e := s.Next(1000)
	must(e)
	b, e := s.Next(1000)
	must(e)
	fmt.Println("same ms distinct:", a != b, "ordered:", a < b)
	_, e = s.Next(999)
	fmt.Println("rollback:", e)
	j := JobLedger{done: map[string]bool{}}
	fmt.Println("job first/replay:", j.Run("billing@2026-10-13T09:00Z"), j.Run("billing@2026-10-13T09:00Z"), "effects:", j.Effects)
}
func must(e error) {
	if e != nil {
		panic(e)
	}
}
