<?php

namespace App\Services;

use Illuminate\Support\Carbon;
use Cache;

class SnowflakeService {

	public static function byDate(Carbon $ts = null)
	{
		if($ts instanceOf Carbon) {
			$ts = now()->parse($ts)->timestamp;
		} else {
			return self::next();
		}

		return ((round($ts * 1000) - 1549756800000) << 22)
		| (random_int(1,31) << 17)
		| (random_int(1,31) << 12)
		| 0;
	}

	public static function next()
	{
		$seq = Cache::get('snowflake:seq');

		if(!$seq) {
			Cache::put('snowflake:seq', 1);
			$seq = 1;
		} else {
			Cache::increment('snowflake:seq');
		}

		if($seq >= 4095) {
			Cache::put('snowflake:seq', 0);
			$seq = 0;
		}

		return ((round(microtime(true) * 1000) - 1549756800000) << 22)
		| (random_int(1,31) << 17)
		| (random_int(1,31) << 12)
		| $seq;
	}

}