<?php
/**
 * Data Collector for Profiler Toolbar
 *
 * @author Elze Kool <info@visualmedia.nl>
 */

namespace VisualM\TagManagerBundle\DataCollector;

use Exception;
use Serializable;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\DataCollector\DataCollector;
use Symfony\Component\HttpKernel\DataCollector\DataCollectorInterface;

/**
 * Data Collector for Profiler Toolbar
 *
 * @author e.kool
 */
class TagDataCollector extends DataCollector implements DataCollectorInterface, Serializable
{   

    /**
     * ContentId (Not serialized!)
     * @var string
     */
    private $contentId;

    /**
     * Collected Content Ids (Not serialized!)
     * @var array
     */
    private $collectedContentIds;

    /**
     * Collected Tags (Not serialized!)
     * @var array
     */
    private $collectedTags;

    /**
     * Available data (Not serialized!)
     * @var array
     */
    private $availableData;


    /**
     * {@inheritDoc}
     */
    public function collect(Request $request, Response $response, Exception $exception = null)
    {
        $this->data = [
            'content_id' => $this->contentId,
            'collected_content_ids' => $this->collectedContentIds,
            'collected_tags' => $this->collectedTags,
            'available_data' => $this->availableData
        ];
    }

    /**
     * Update ContentId that is used
     *
     * @param string $contentId ContentId
     */
    public function updateContentId($contentId)
    {
        $this->contentId = $contentId;
    }

    /**
     * Add Collected ContentIds
     *
     * @param string $contentId ContentId
     */
    public function addCollectedContentId($contentId)
    {
        if ($this->collectedContentIds === null) {
            $this->collectedContentIds = [];
        }
        $this->collectedContentIds[] = $contentId;
    }

    /**
     * Collect/Add Tag
     *
     * @param CollectionItem $item Tag
     */
    public function addTag(CollectionItem $item)
    {
        if ($this->collectedTags === null) {
            $this->collectedTags = [];
        }
        $this->collectedTags[] = $item;
    }

    /**
     * Update Available Data array
     *
     * @param array $availableData Available data
     */
    public function updateAvailableData($availableData)
    {
        $this->availableData = $availableData;
    }

    /**
     * Get ContentId
     * @return string
     */
    public function getContentId()
    {
        return ($this->contentId === null) ? $this->data['content_id'] : $this->contentId;
    }

    /**
     * Get Collected Content Ids
     *
     * @return array Collected Content Ids
     */
    public function getCollectedContentIds()
    {
        $collected = ($this->collectedContentIds === null) ? $this->data['collected_content_ids'] : $this->collectedContentIds;
        $collected = $collected === null ? [] : $collected;
        return $collected;
    }

    /**
     * Get Collected Tags
     *
     * @return array Collected Tags
     */
    public function getCollectedTags()
    {
        $collected = ($this->collectedTags === null) ? $this->data['collected_tags'] : $this->collectedTags;
        $collected = $collected === null ? [] : $collected;
        return $collected;
    }

    /**
     * Get Available Data
     *
     * @return array Available Data
     */
    public function getAvailableData()
    {
        // First fetch available data
        $available_data = ($this->availableData === null) ? $this->data['available_data'] : $this->availableData;
        $available_data = $available_data === null ? [] : $available_data;

        // Then flatten it
        $flattened_available_data = [];
        foreach($available_data as $key => $data_element) {
            if (!is_string($data_element)) {
                foreach((array) $data_element as $subkey => $subdata_element) {
                    $flattened_available_data[$key . '.' . $subkey] = $subdata_element;
                }
            } else {
                $flattened_available_data[$key] = $data_element;
            }
        }

        return $flattened_available_data;
    }

    /**
     * Check if Collected Tags contains Errors
     *
     * @return boolean Contains Errors
     */
    public function getCollectedTagHasErrors()
    {
        foreach($this->getCollectedTags() as $tag) {
            if ($tag->getExceptions() != '') {
                return true;
            }
        }
        return false;
    }

    /**
     * {@inheritDoc}
     */
    public function getName()
    {
        return 'visualm_tag';
    }
}
