<?php
namespace Fifa\ConnectId\Sdk\Util\ArrayUtils;

use InvalidArgumentException;

/**
 * Class ArrayParser
 * @package Fifa\ConnectId\Sdk\Util\ArrayUtils
 */
class ArrayParser
{
    /**
     * @var array
     */
    private $data;

    /**
     * Creates an instance of ArrayParser
     *
     * @param array $data
     * @return ArrayParser
     */
    public static function create(array $data): ArrayParser
    {
        return new ArrayParser($data);
    }

    /**
     * Constructor
     *
     * @param array $data
     */
    public function __construct(array $data)
    {
        $this->data = $data;
    }

    /**
     * Verifies that array contains only instance of given type
     *
     * @param string $className
     * @return ArrayParser
     * @throws InvalidArgumentException
     */
    public function checkContainsOnlyInstancesOf(string $className): ArrayParser
    {
        foreach ($this->data as $item) {
            if (!$item instanceof $className) {
                throw new InvalidArgumentException(sprintf(
                    'Array can contain only instances of "%s", "%s" is not accepted',
                    $className,
                    is_object($item) ? get_class($item) : gettype($item)
                ));
            }
        }

        return $this;
    }

    /**
     * Throws an exception in case when array is empty
     *
     * @param string|null $message
     * @return ArrayParser
     */
    public function checkNotEmpty(string $message = null): ArrayParser
    {
        $message = is_string($message) ? $message : 'Array can\'t be empty.';

        if (count($this->data) == 0) {
            throw new InvalidArgumentException($message);
        }

        return $this;
    }

    /**
     * Removes duplicates from the array
     *
     * @param DuplicatesFilterInterface $duplicatesFilter
     * @return ArrayParser
     */
    public function removeDuplicates(DuplicatesFilterInterface $duplicatesFilter): ArrayParser
    {
        $this->data = $duplicatesFilter->filterDuplicates($this->data);
        
        return $this;
    }

    /**
     * Returns the array
     *
     * @return array
     */
    public function getData(): array
    {
        return $this->data;
    }
}