<?php

namespace App\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;

class CompressedStringOrNull implements CastsAttributes
{
	/**
	 * Cast the given value.
	 *
	 * @param Model $model
	 * @param string $key
	 * @param mixed $value
	 * @param array $attributes
	 * @return string|null
	 * @note postgres bytea columns the value is a resource stream
	 */
	public function get(Model $model,string $key,mixed $value,array $attributes): ?string
	{
		// For stream resources, we to fseek in case we've already read it.
		if (is_resource($value))
			fseek($value,0);

		$value = is_resource($value)
			? stream_get_contents($value)
			: $value;

		return $value ? zstd_uncompress(base64_decode($value)) : NULL;
	}

	/**
	 * Prepare the given value for storage.
	 *
	 * @param Model $model
	 * @param string $key
	 * @param mixed $value
	 * @param array $attributes
	 * @return string|null
	 */
	public function set(Model $model,string $key,$value,array $attributes): ?string
	{
		return $value ? base64_encode(zstd_compress($value)) : NULL;
	}
}