<commit_before><commit_msg>Add hash key data builder<commit_after><?php declare(strict_types=1);

namespace hollodotme\Readis\Application\ReadModel\KeyDataBuilders;

use hollodotme\Readis\Application\Interfaces\ProvidesKeyInfo;
use hollodotme\Readis\Application\ReadModel\Constants\KeyType;
use hollodotme\Readis\Application\ReadModel\DTO\KeyData;
use hollodotme\Readis\Application\ReadModel\Interfaces\BuildsKeyData;
use hollodotme\Readis\Application\ReadModel\Interfaces\PrettifiesString;
use hollodotme\Readis\Application\ReadModel\Interfaces\ProvidesKeyData;
use hollodotme\Readis\Application\ReadModel\Interfaces\ProvidesKeyName;
use hollodotme\Readis\Infrastructure\Redis\Exceptions\ConnectionFailedException;
use hollodotme\Readis\Infrastructure\Redis\ServerManager;

final class HashKeyDataBuilder implements BuildsKeyData
{
	private const FIELD_SEPARATOR = "\n\n---\n\n";

	/** @var ServerManager */
	private $manager;

	/** @var PrettifiesString */
	private $prettifier;

	public function __construct( ServerManager $manager, PrettifiesString $prettifier )
	{
		$this->manager    = $manager;
		$this->prettifier = $prettifier;
	}

	public function canBuildKeyData( ProvidesKeyInfo $keyInfo, ProvidesKeyName $keyName ) : bool
	{
		return !$keyName->hasSubKey() && (KeyType::HASH === $keyInfo->getType());
	}

	/**
	 * @param ProvidesKeyInfo $keyInfo
	 * @param ProvidesKeyName $keyName
	 *
	 * @throws ConnectionFailedException
	 * @return ProvidesKeyData
	 */
	public function buildKeyData( ProvidesKeyInfo $keyInfo, ProvidesKeyName $keyName ) : ProvidesKeyData
	{
		$rawFields  = [];
		$hashValues = $this->manager->getAllHashValues( $keyName->getKeyName() );

		foreach ( $hashValues as $hashKey => $hashValue )
		{
			$rawFields[] = $this->getFieldOutput( $hashKey, $hashValue );
		}

		$prettyFields = [];
		foreach ( $hashValues as $hashKey => $hashValue )
		{
			$prettyHashValue = $this->prettifier->prettify( $hashValue );
			$prettyFields[]  = $this->getFieldOutput( $hashKey, $prettyHashValue );
		}

		$rawKeyData = implode( self::FIELD_SEPARATOR, $rawFields );
		$keyData    = implode( self::FIELD_SEPARATOR, $prettyFields );

		return new KeyData( $keyData, $rawKeyData );
	}

	private function getFieldOutput( string $hashKey, string $hashValue ) : string
	{
		return sprintf(
			"Hash key %s:\n%s\n%s",
			$hashKey,
			str_repeat( '=', 10 + strlen( (string)$hashKey ) ),
			$hashValue
		);
	}
}
{'fraction_non_alphanumeric': 0.1281521289789169, 'fraction_numerical': 0.0012401818933443572, 'mean_word_length': 5.269430051813472, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 16, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4043885', 'n_tokens_mistral': 851, 'n_tokens_neox': 801, 'n_words': 142}