package config

import (
	"encoding/json"
	"errors"
	"math/rand"
	"strings"
	"time"
)

type Duration struct {
	least time.Duration
	most  time.Duration
}

func (d Duration) Get() time.Duration {
	if d.least == 0 {
		d.least = time.Second
	}
	jitter := d.most - d.least
	if jitter >= time.Second {
		jitter = time.Second * time.Duration(rand.Int()%int(jitter.Seconds()))
	} else {
		jitter = 0
	}
	return time.Duration(d.least + jitter)
}

func (d Duration) MarshalJSON() ([]byte, error) {
	return json.Marshal(d.least.String() + ".." + d.most.String())
}

func (d *Duration) UnmarshalJSON(b []byte) error {
	var s string
	if err := json.Unmarshal(b, &s); err != nil {
		return err
	}
	if !strings.Contains(s, "..") {
		s = s + ".." + s
	}
	splits := strings.Split(s, "..")
	if len(splits) != 2 {
		return errors.New("unexpected ..")
	}
	least, err := time.ParseDuration(splits[0])
	if err != nil {
		return err
	}
	most, err := time.ParseDuration(splits[1])
	if err != nil {
		return err
	}
	if least > most {
		most, least = least, most
	}
	d.most = most
	d.least = least
	return nil
}
