<?php

namespace FCA\StockApi\Tests\Unit\Document;

use FCA\StockApi\Exception\ApiException;
use PHPUnit\Framework\TestCase;
use \FCA\StockApi\Document\Offer;

class OfferDocumentTest extends TestCase
{
    /**
     * Metoda sprawdzająca rekurencyjnie poprawność danych zwracanych przez gettery obiektów typu FCA\StockApi\Document\*
     * z danymi wygenerowanymi przez metodę toArray()
     * @param $array
     * @param $object
     * @return bool
     */
    private function checkDataArray($array, $object)
    {
        foreach ($array as $key => $value) {
            $getMethodName = "get" . strtoupper(substr($key, 0, 1)) . substr($key, 1);
            if (is_array($value) and count($value) > 0 and is_int(array_keys($value)[0]) and is_array($value[0])) {
                foreach ($value as $k => $v) {
                    if (!$this->checkDataArray($v, $object->{$getMethodName}()[$k])) {
                        return false;
                    }
                }
            } else {
                if (is_array($value) and count($value) > 0 and !is_int(array_keys($value)[0])) {
                    if (!$this->checkDataArray($value, $object->{$getMethodName}())) {
                        return false;
                    }
                } else {
                    if (is_array($object)) {
                        return $object === $array;
                    }
                    if ($object->{$getMethodName}() != $value) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /**
     * Test działania klasy na podstawie poprawnych danych wejściowych
     * @throws \FCA\StockApi\Exception\ApiException
     */
    public function testOfferDocumentWithValidValues()
    {
        $data = json_decode(file_get_contents(__DIR__ . '/offerValid.json'), true, 8);
        $dataAsArray = json_decode(file_get_contents(__DIR__ . '/offerArray.json'), true, 8);
        $dataAsSimpleArray = json_decode(file_get_contents(__DIR__ . '/offerSimpleArray.json'), true);

        $offer = new Offer($data);
        $this->assertInstanceOf(Offer::class, $offer);

        // Sprawdzenie, czy dane zwrócone przez metodę toArray są poprawne
        $this->assertEquals($dataAsArray, $offer->toArray());

        // Analogiczne do powyższego sprawdzenie funkcji `toSimpleArray()`
        $this->assertEquals($dataAsSimpleArray, $offer->toSimpleArray());

        // Sprawdzenie, czy dane zwracane przez gettery są poprawne - identyczne jak te zwracane przez metodę toArray()
        $this->assertTrue($this->checkDataArray($offer->toArray(), $offer));
    }

    /**
     * Test działania klasy na podstawie błędnych danych
     * @throws ApiException
     */
    public function testOfferDocumentWithInvalidValues()
    {
        $data = json_decode(file_get_contents(__DIR__ . '/offerValid.json'), true, 8);

        // usuwamy wymagany element tablicy
        unset($data['brand']);

        // oczekujemy wyjątku
        $this->expectException(ApiException::class);
        new Offer($data);
    }
}
