<?php

/*
 * Copyright (C) 2015 IRSTEA
 * All rights reserved.
 */

namespace Irstea\FileUploadBundle\Form\DataTranformer;

use Irstea\FileUploadBundle\Model\FileManagerInterface;
use Irstea\FileUploadBundle\Model\UploadedFileInterface;
use Symfony\Component\Form\DataTransformerInterface;
use Symfony\Component\Form\Exception\TransformationFailedException;
use Traversable;

/**
 * Description of UploadedFileTransformer
 */
class UploadedFileTransformer implements DataTransformerInterface
{
    /**
     *
     * @var boolean
     */
    private $multiple;

    /**
     *
     * @var FileManagerInterface
     */
    private $fileManager;

    public function __construct(FileManagerInterface $fileManager, $multiple = false)
    {
        $this->fileManager = $fileManager;
        $this->multiple = $multiple;
    }

    /**
     * {@inheritdoc}
     */
    public function reverseTransform($value)
    {
        if(!$this->multiple) {
            return $this->reverseTransformFile($value);
        }

        if(empty($value)) {
            return [];
        }

        if(!is_array($value) && !$value instanceof Traversable) {
            throw new TransformationFailedException('Expected an array or a \Traversable.');
        }

        $result = [];
        foreach($value as $identifier) {
            if(null !== $file = $this->reverseTransformFile($identifier)) {
                $result[] = $file;
            }
        }
        return $result;
    }

    /**
     * {@inheritdoc}
     */
    public function transform($value)
    {
        if(!$this->multiple) {
            return $this->transformFile($value);
        }

        if(empty($value)) {
            return [];
        }

        if(!is_array($value) && !$value instanceof Traversable) {
            throw new TransformationFailedException('Expected an array or a \Traversable.');
        }

        $result = [];
        foreach($value as $file) {
            if(null !== $item = $this->transformFile($file)) {
                $result[] = $item;
            }
        }

        return $result;
    }

    /**
     *
     * @param mixed $value
     * @return mixed
     */
    public function transformFile($value)
    {
        if(empty($value)) {
            return null;
        }

        if(!$value instanceof UploadedFileInterface) {
            throw new TransformationFailedException('Expected an UploadedFileInterface.');
        }

        return $value->toArray();
    }

    /**
     *
     * @param mixed $value
     * @return UploadedFileInterface
     */
    public function reverseTransformFile($value)
    {
        if(empty($value)) {
            return null;
        }

        if(!is_array($value)) {
            throw new TransformationFailedException(sprintf('Expected an array, not a %s.', is_object($value) ? get_class($value) : gettype($value)));
        }

        if(empty($value['id'])) {
            return null;
        }

        $identifier = $value['id'];

        $file = $this->fileManager->get($identifier);
        if(null === $file) {
            return null;
        }

        if($file->isOrphelin()) {
            $file->setEtat(UploadedFileInterface::ETAT_NORMAL);
        }
        $file->setDescription(!empty($value['description']) ? $value['description'] : null);

        return $file;
    }
}