// Copyright 2016 The Oklog Authors
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package ulid

import (
	
	
	
	
	
	
	
	
	
	
)

/*
An ULID is a 16 byte Universally Unique Lexicographically Sortable Identifier

	The components are encoded as 16 octets.
	Each component is encoded with the MSB first (network byte order).

	0                   1                   2                   3
	0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|                      32_bit_uint_time_high                    |
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|     16_bit_uint_time_low      |       16_bit_uint_random      |
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|                       32_bit_uint_random                      |
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
	|                       32_bit_uint_random                      |
	+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
type ULID [16]byte

var (
	// ErrDataSize is returned when parsing or unmarshaling ULIDs with the wrong
	// data size.
	ErrDataSize = errors.New("ulid: bad data size when unmarshaling")

	// ErrInvalidCharacters is returned when parsing or unmarshaling ULIDs with
	// invalid Base32 encodings.
	ErrInvalidCharacters = errors.New("ulid: bad data characters when unmarshaling")

	// ErrBufferSize is returned when marshalling ULIDs to a buffer of insufficient
	// size.
	ErrBufferSize = errors.New("ulid: bad buffer size when marshaling")

	// ErrBigTime is returned when constructing an ULID with a time that is larger
	// than MaxTime.
	ErrBigTime = errors.New("ulid: time too big")

	// ErrOverflow is returned when unmarshaling a ULID whose first character is
	// larger than 7, thereby exceeding the valid bit depth of 128.
	ErrOverflow = errors.New("ulid: overflow when unmarshaling")

	// ErrMonotonicOverflow is returned by a Monotonic entropy source when
	// incrementing the previous ULID's entropy bytes would result in overflow.
	ErrMonotonicOverflow = errors.New("ulid: monotonic entropy overflow")

	// ErrScanValue is returned when the value passed to scan cannot be unmarshaled
	// into the ULID.
	ErrScanValue = errors.New("ulid: source value must be a string or byte slice")
)

// New returns an ULID with the given Unix milliseconds timestamp and an
// optional entropy source. Use the Timestamp function to convert
// a time.Time to Unix milliseconds.
//
// ErrBigTime is returned when passing a timestamp bigger than MaxTime.
// Reading from the entropy source may also return an error.
func ( uint64,  io.Reader) ( ULID,  error) {
	if  = .SetTime();  != nil {
		return , 
	}

	switch e := .(type) {
	case nil:
		return , 
	case *monotonic:
		 = .MonotonicRead(, [6:])
	default:
		_,  = io.ReadFull(, [6:])
	}

	return , 
}

// MustNew is a convenience function equivalent to New that panics on failure
// instead of returning an error.
func ( uint64,  io.Reader) ULID {
	,  := New(, )
	if  != nil {
		panic()
	}
	return 
}

// Parse parses an encoded ULID, returning an error in case of failure.
//
// ErrDataSize is returned if the len(ulid) is different from an encoded
// ULID's length. Invalid encodings produce undefined ULIDs. For a version that
// returns an error instead, see ParseStrict.
func ( string) ( ULID,  error) {
	return , parse([]byte(), false, &)
}

// ParseStrict parses an encoded ULID, returning an error in case of failure.
//
// It is like Parse, but additionally validates that the parsed ULID consists
// only of valid base32 characters. It is slightly slower than Parse.
//
// ErrDataSize is returned if the len(ulid) is different from an encoded
// ULID's length. Invalid encodings return ErrInvalidCharacters.
func ( string) ( ULID,  error) {
	return , parse([]byte(), true, &)
}

func parse( []byte,  bool,  *ULID) error {
	// Check if a base32 encoded ULID is the right length.
	if len() != EncodedSize {
		return ErrDataSize
	}

	// Check if all the characters in a base32 encoded ULID are part of the
	// expected base32 character set.
	if  &&
		(dec[[0]] == 0xFF ||
			dec[[1]] == 0xFF ||
			dec[[2]] == 0xFF ||
			dec[[3]] == 0xFF ||
			dec[[4]] == 0xFF ||
			dec[[5]] == 0xFF ||
			dec[[6]] == 0xFF ||
			dec[[7]] == 0xFF ||
			dec[[8]] == 0xFF ||
			dec[[9]] == 0xFF ||
			dec[[10]] == 0xFF ||
			dec[[11]] == 0xFF ||
			dec[[12]] == 0xFF ||
			dec[[13]] == 0xFF ||
			dec[[14]] == 0xFF ||
			dec[[15]] == 0xFF ||
			dec[[16]] == 0xFF ||
			dec[[17]] == 0xFF ||
			dec[[18]] == 0xFF ||
			dec[[19]] == 0xFF ||
			dec[[20]] == 0xFF ||
			dec[[21]] == 0xFF ||
			dec[[22]] == 0xFF ||
			dec[[23]] == 0xFF ||
			dec[[24]] == 0xFF ||
			dec[[25]] == 0xFF) {
		return ErrInvalidCharacters
	}

	// Check if the first character in a base32 encoded ULID will overflow. This
	// happens because the base32 representation encodes 130 bits, while the
	// ULID is only 128 bits.
	//
	// See https://github.com/oklog/ulid/issues/9 for details.
	if [0] > '7' {
		return ErrOverflow
	}

	// Use an optimized unrolled loop (from https://github.com/RobThree/NUlid)
	// to decode a base32 ULID.

	// 6 bytes timestamp (48 bits)
	(*)[0] = ((dec[[0]] << 5) | dec[[1]])
	(*)[1] = ((dec[[2]] << 3) | (dec[[3]] >> 2))
	(*)[2] = ((dec[[3]] << 6) | (dec[[4]] << 1) | (dec[[5]] >> 4))
	(*)[3] = ((dec[[5]] << 4) | (dec[[6]] >> 1))
	(*)[4] = ((dec[[6]] << 7) | (dec[[7]] << 2) | (dec[[8]] >> 3))
	(*)[5] = ((dec[[8]] << 5) | dec[[9]])

	// 10 bytes of entropy (80 bits)
	(*)[6] = ((dec[[10]] << 3) | (dec[[11]] >> 2))
	(*)[7] = ((dec[[11]] << 6) | (dec[[12]] << 1) | (dec[[13]] >> 4))
	(*)[8] = ((dec[[13]] << 4) | (dec[[14]] >> 1))
	(*)[9] = ((dec[[14]] << 7) | (dec[[15]] << 2) | (dec[[16]] >> 3))
	(*)[10] = ((dec[[16]] << 5) | dec[[17]])
	(*)[11] = ((dec[[18]] << 3) | dec[[19]]>>2)
	(*)[12] = ((dec[[19]] << 6) | (dec[[20]] << 1) | (dec[[21]] >> 4))
	(*)[13] = ((dec[[21]] << 4) | (dec[[22]] >> 1))
	(*)[14] = ((dec[[22]] << 7) | (dec[[23]] << 2) | (dec[[24]] >> 3))
	(*)[15] = ((dec[[24]] << 5) | dec[[25]])

	return nil
}

// MustParse is a convenience function equivalent to Parse that panics on failure
// instead of returning an error.
func ( string) ULID {
	,  := Parse()
	if  != nil {
		panic()
	}
	return 
}

// MustParseStrict is a convenience function equivalent to ParseStrict that
// panics on failure instead of returning an error.
func ( string) ULID {
	,  := ParseStrict()
	if  != nil {
		panic()
	}
	return 
}

// String returns a lexicographically sortable string encoded ULID
// (26 characters, non-standard base 32) e.g. 01AN4Z07BY79KA1307SR9X4MV3
// Format: tttttttttteeeeeeeeeeeeeeee where t is time and e is entropy
func ( ULID) () string {
	 := make([]byte, EncodedSize)
	_ = .MarshalTextTo()
	return string()
}

// MarshalBinary implements the encoding.BinaryMarshaler interface by
// returning the ULID as a byte slice.
func ( ULID) () ([]byte, error) {
	 := make([]byte, len())
	return , .MarshalBinaryTo()
}

// MarshalBinaryTo writes the binary encoding of the ULID to the given buffer.
// ErrBufferSize is returned when the len(dst) != 16.
func ( ULID) ( []byte) error {
	if len() != len() {
		return ErrBufferSize
	}

	copy(, [:])
	return nil
}

// UnmarshalBinary implements the encoding.BinaryUnmarshaler interface by
// copying the passed data and converting it to an ULID. ErrDataSize is
// returned if the data length is different from ULID length.
func ( *ULID) ( []byte) error {
	if len() != len(*) {
		return ErrDataSize
	}

	copy((*)[:], )
	return nil
}

// Encoding is the base 32 encoding alphabet used in ULID strings.
const Encoding = "0123456789ABCDEFGHJKMNPQRSTVWXYZ"

// MarshalText implements the encoding.TextMarshaler interface by
// returning the string encoded ULID.
func ( ULID) () ([]byte, error) {
	 := make([]byte, EncodedSize)
	return , .MarshalTextTo()
}

// MarshalTextTo writes the ULID as a string to the given buffer.
// ErrBufferSize is returned when the len(dst) != 26.
func ( ULID) ( []byte) error {
	// Optimized unrolled loop ahead.
	// From https://github.com/RobThree/NUlid

	if len() != EncodedSize {
		return ErrBufferSize
	}

	// 10 byte timestamp
	[0] = Encoding[([0]&224)>>5]
	[1] = Encoding[[0]&31]
	[2] = Encoding[([1]&248)>>3]
	[3] = Encoding[(([1]&7)<<2)|(([2]&192)>>6)]
	[4] = Encoding[([2]&62)>>1]
	[5] = Encoding[(([2]&1)<<4)|(([3]&240)>>4)]
	[6] = Encoding[(([3]&15)<<1)|(([4]&128)>>7)]
	[7] = Encoding[([4]&124)>>2]
	[8] = Encoding[(([4]&3)<<3)|(([5]&224)>>5)]
	[9] = Encoding[[5]&31]

	// 16 bytes of entropy
	[10] = Encoding[([6]&248)>>3]
	[11] = Encoding[(([6]&7)<<2)|(([7]&192)>>6)]
	[12] = Encoding[([7]&62)>>1]
	[13] = Encoding[(([7]&1)<<4)|(([8]&240)>>4)]
	[14] = Encoding[(([8]&15)<<1)|(([9]&128)>>7)]
	[15] = Encoding[([9]&124)>>2]
	[16] = Encoding[(([9]&3)<<3)|(([10]&224)>>5)]
	[17] = Encoding[[10]&31]
	[18] = Encoding[([11]&248)>>3]
	[19] = Encoding[(([11]&7)<<2)|(([12]&192)>>6)]
	[20] = Encoding[([12]&62)>>1]
	[21] = Encoding[(([12]&1)<<4)|(([13]&240)>>4)]
	[22] = Encoding[(([13]&15)<<1)|(([14]&128)>>7)]
	[23] = Encoding[([14]&124)>>2]
	[24] = Encoding[(([14]&3)<<3)|(([15]&224)>>5)]
	[25] = Encoding[[15]&31]

	return nil
}

// Byte to index table for O(1) lookups when unmarshaling.
// We use 0xFF as sentinel value for invalid indexes.
var dec = [...]byte{
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
	0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
	0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14, 0x15, 0xFF,
	0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C, 0x1D, 0x1E,
	0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
	0x0D, 0x0E, 0x0F, 0x10, 0x11, 0xFF, 0x12, 0x13, 0xFF, 0x14,
	0x15, 0xFF, 0x16, 0x17, 0x18, 0x19, 0x1A, 0xFF, 0x1B, 0x1C,
	0x1D, 0x1E, 0x1F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
}

// EncodedSize is the length of a text encoded ULID.
const EncodedSize = 26

// UnmarshalText implements the encoding.TextUnmarshaler interface by
// parsing the data as string encoded ULID.
//
// ErrDataSize is returned if the len(v) is different from an encoded
// ULID's length. Invalid encodings produce undefined ULIDs.
func ( *ULID) ( []byte) error {
	return parse(, false, )
}

// Time returns the Unix time in milliseconds encoded in the ULID.
// Use the top level Time function to convert the returned value to
// a time.Time.
func ( ULID) () uint64 {
	return uint64([5]) | uint64([4])<<8 |
		uint64([3])<<16 | uint64([2])<<24 |
		uint64([1])<<32 | uint64([0])<<40
}

// maxTime is the maximum Unix time in milliseconds that can be
// represented in an ULID.
var maxTime = ULID{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}.Time()

// MaxTime returns the maximum Unix time in milliseconds that
// can be encoded in an ULID.
func () uint64 { return maxTime }

// Now is a convenience function that returns the current
// UTC time in Unix milliseconds. Equivalent to:
//   Timestamp(time.Now().UTC())
func () uint64 { return Timestamp(time.Now().UTC()) }

// Timestamp converts a time.Time to Unix milliseconds.
//
// Because of the way ULID stores time, times from the year
// 10889 produces undefined results.
func ( time.Time) uint64 {
	return uint64(.Unix())*1000 +
		uint64(.Nanosecond()/int(time.Millisecond))
}

// Time converts Unix milliseconds in the format
// returned by the Timestamp function to a time.Time.
func ( uint64) time.Time {
	 := int64( / 1e3)
	 := int64(( % 1e3) * 1e6)
	return time.Unix(, )
}

// SetTime sets the time component of the ULID to the given Unix time
// in milliseconds.
func ( *ULID) ( uint64) error {
	if  > maxTime {
		return ErrBigTime
	}

	(*)[0] = byte( >> 40)
	(*)[1] = byte( >> 32)
	(*)[2] = byte( >> 24)
	(*)[3] = byte( >> 16)
	(*)[4] = byte( >> 8)
	(*)[5] = byte()

	return nil
}

// Entropy returns the entropy from the ULID.
func ( ULID) () []byte {
	 := make([]byte, 10)
	copy(, [6:])
	return 
}

// SetEntropy sets the ULID entropy to the passed byte slice.
// ErrDataSize is returned if len(e) != 10.
func ( *ULID) ( []byte) error {
	if len() != 10 {
		return ErrDataSize
	}

	copy((*)[6:], )
	return nil
}

// Compare returns an integer comparing id and other lexicographically.
// The result will be 0 if id==other, -1 if id < other, and +1 if id > other.
func ( ULID) ( ULID) int {
	return bytes.Compare([:], [:])
}

// Scan implements the sql.Scanner interface. It supports scanning
// a string or byte slice.
func ( *ULID) ( interface{}) error {
	switch x := .(type) {
	case nil:
		return nil
	case string:
		return .UnmarshalText([]byte())
	case []byte:
		return .UnmarshalBinary()
	}

	return ErrScanValue
}

// Value implements the sql/driver.Valuer interface. This returns the value
// represented as a byte slice. If instead a string is desirable, a wrapper
// type can be created that calls String().
//
//	// stringValuer wraps a ULID as a string-based driver.Valuer.
// 	type stringValuer ULID
//
//	func (id stringValuer) Value() (driver.Value, error) {
//		return ULID(id).String(), nil
//	}
//
//	// Example usage.
//	db.Exec("...", stringValuer(id))
func ( ULID) () (driver.Value, error) {
	return .MarshalBinary()
}

// Monotonic returns an entropy source that is guaranteed to yield
// strictly increasing entropy bytes for the same ULID timestamp.
// On conflicts, the previous ULID entropy is incremented with a
// random number between 1 and `inc` (inclusive).
//
// The provided entropy source must actually yield random bytes or else
// monotonic reads are not guaranteed to terminate, since there isn't
// enough randomness to compute an increment number.
//
// When `inc == 0`, it'll be set to a secure default of `math.MaxUint32`.
// The lower the value of `inc`, the easier the next ULID within the
// same millisecond is to guess. If your code depends on ULIDs having
// secure entropy bytes, then don't go under this default unless you know
// what you're doing.
//
// The returned io.Reader isn't safe for concurrent use.
func ( io.Reader,  uint64) io.Reader {
	 := monotonic{
		Reader: bufio.NewReader(),
		inc:    ,
	}

	if .inc == 0 {
		.inc = math.MaxUint32
	}

	if ,  := .(*rand.Rand);  {
		.rng = 
	}

	return &
}

type monotonic struct {
	io.Reader
	ms      uint64
	inc     uint64
	entropy uint80
	rand    [8]byte
	rng     *rand.Rand
}

func ( *monotonic) ( uint64,  []byte) ( error) {
	if !.entropy.IsZero() && .ms ==  {
		 = .increment()
		.entropy.AppendTo()
	} else if _,  = io.ReadFull(.Reader, );  == nil {
		.ms = 
		.entropy.SetBytes()
	}
	return 
}

// increment the previous entropy number with a random number
// of up to m.inc (inclusive).
func ( *monotonic) () error {
	if ,  := .random();  != nil {
		return 
	} else if .entropy.Add() {
		return ErrMonotonicOverflow
	}
	return nil
}

// random returns a uniform random value in [1, m.inc), reading entropy
// from m.Reader. When m.inc == 0 || m.inc == 1, it returns 1.
// Adapted from: https://golang.org/pkg/crypto/rand/#Int
func ( *monotonic) () ( uint64,  error) {
	if .inc <= 1 {
		return 1, nil
	}

	// Fast path for using a underlying rand.Rand directly.
	if .rng != nil {
		// Range: [1, m.inc)
		return 1 + uint64(.rng.Int63n(int64(.inc))), nil
	}

	// bitLen is the maximum bit length needed to encode a value < m.inc.
	 := bits.Len64(.inc)

	// byteLen is the maximum byte length needed to encode a value < m.inc.
	 := uint(+7) / 8

	// msbitLen is the number of bits in the most significant byte of m.inc-1.
	 := uint( % 8)
	if  == 0 {
		 = 8
	}

	for  == 0 ||  >= .inc {
		if _,  = io.ReadFull(.Reader, .rand[:]);  != nil {
			return 0, 
		}

		// Clear bits in the first byte to increase the probability
		// that the candidate is < m.inc.
		.rand[0] &= uint8(int(1<<) - 1)

		// Convert the read bytes into an uint64 with byteLen
		// Optimized unrolled loop.
		switch  {
		case 1:
			 = uint64(.rand[0])
		case 2:
			 = uint64(binary.LittleEndian.Uint16(.rand[:2]))
		case 3, 4:
			 = uint64(binary.LittleEndian.Uint32(.rand[:4]))
		case 5, 6, 7, 8:
			 = uint64(binary.LittleEndian.Uint64(.rand[:8]))
		}
	}

	// Range: [1, m.inc)
	return 1 + , nil
}

type uint80 struct {
	Hi uint16
	Lo uint64
}

func ( *uint80) ( []byte) {
	.Hi = binary.BigEndian.Uint16([:2])
	.Lo = binary.BigEndian.Uint64([2:])
}

func ( *uint80) ( []byte) {
	binary.BigEndian.PutUint16([:2], .Hi)
	binary.BigEndian.PutUint64([2:], .Lo)
}

func ( *uint80) ( uint64) ( bool) {
	,  := .Lo, .Hi
	if .Lo += ; .Lo <  {
		.Hi++
	}
	return .Hi < 
}

func ( uint80) () bool {
	return .Hi == 0 && .Lo == 0
}