<?php
/**
 * Copyright 2020 Adobe
 * All Rights Reserved.
 *
 * NOTICE: Adobe permits you to use, modify, and distribute this file in
 * accordance with the terms of the Adobe license agreement accompanying
 * it.
 */
declare(strict_types=1);

namespace Magento\Mray\Index\Collection;

use RuntimeException;
use function hash;
use function strlen;

class Dictionary implements DataCollection
{
    /** @var array  */
    private $data = [];

    /**
     * @param string $data
     * @return string
     */
    public function write(string $data): string
    {
        $ref = $this->generateHash($data);
        if (strlen($ref) >= strlen($data)) {
            $ref = $data;
            $data = 0;
        }

        if ($data !== ($this->data[$ref] ?? $data)) {
            throw new RuntimeException('Dictionary write operation failed. Collision.');
        }
        $this->data[$ref] = $data;
        return $ref;
    }

    /**
     * @param string $ref
     * @return string|null
     */
    public function read(string $ref): ?string
    {
        $val = $this->data[$ref] ?? null;
        if ($val) {
            return $val;
        } elseif ($val === 0) {
            return $ref;
        } else {
            return null;
        }
    }

    /**
     * @param string $data
     * @return string
     */
    private function generateHash(string $data): string
    {
        return str_replace(
            ['+', '/', '='],
            ['-', '_', ''],
            base64_encode(hash('md5', $data, true))
        );
    }

    /**
     * @inheritDoc
     */
    public function exportData(): array
    {
        return $this->data;
    }

    /**
     * @param array $data
     */
    public function importData(array $data): void
    {
        foreach ($data as $k => $v) {
            $this->data[$k] = $v;
        }
    }
}
