<?php

namespace Comitium5\DesignerBundle\DataFixtures\Abstracts;

use Doctrine\Common\DataFixtures\AbstractFixture as DoctrineAbstractFixture;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Yaml\Yaml;
use Faker\Factory as Faker;

/**
 * Class AbstractFixture
 *
 * @author Oscar Jimenez <oscarjg19.developer@gmail.com>
 * @package  Comitium5\DesignerBundle\DataFixtures\Abstracts
 */
abstract class AbstractFixture extends DoctrineAbstractFixture implements ContainerAwareInterface
{
    /**
     * @var ContainerInterface
     */
    protected $container;

    /**
     * Sets the Container.
     *
     * @param ContainerInterface|null $container A ContainerInterface instance or null
     *
     * @api
     */
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    /**
     * Return fixture data by type
     *
     * @param $type
     *
     * @return mixed
     */
    public function getFixtureData($type)
    {
        $env = $this->getEnvironment();

        if ($env === "dev") {
            $file = self::fixturesDevPath()."$type.yml";

            if (file_exists($file)) {
                return Yaml::parse($file);
            }
        }

        if ($env === "prod") {
            $file = self::fixturesProdPath()."$type.yml";

            if (file_exists($file)) {
                return Yaml::parse($file);
            }
        }
    }

    /**
     *
     * @param array $fixtureData
     * @param $reference
     *
     * @return mixed
     * @throws \Exception
     */
    public static function getFixtureReference(array $fixtureData, $reference)
    {
        $match = array_filter($fixtureData, function ($data) use ($reference) {
            if ($data['reference'] === $reference) {
                return $data;
            }
        });

        if (!count($match)) {
            throw new \Exception('Reference have not matches');
        }

        if (count($match) > 1) {
            throw new \Exception('Duplicate references found');
        }

        return array_shift($match);
    }

    /**
     * @return array
     */
    public function getLocales()
    {
        return [
            $this->getReference("locale[es]"),
            $this->getReference("locale[ca]"),
        ];
    }

    /**
     * @return string
     */
    private static function fixturesDevPath()
    {
        return __DIR__.DIRECTORY_SEPARATOR."..".DIRECTORY_SEPARATOR."DataProvider".DIRECTORY_SEPARATOR."fixtures".DIRECTORY_SEPARATOR."dev".DIRECTORY_SEPARATOR;
    }

    /**
     * @return string
     */
    private static function fixturesProdPath()
    {
        return __DIR__.DIRECTORY_SEPARATOR."..".DIRECTORY_SEPARATOR."DataProvider".DIRECTORY_SEPARATOR."fixtures".DIRECTORY_SEPARATOR."prod".DIRECTORY_SEPARATOR;
    }

    /**
     * @return \Faker\Generator
     */
    protected static function getFaker()
    {
        return Faker::create();
    }

    /**
     * @return string
     */
    protected function getEnvironment()
    {
        return $this
            ->container
            ->get("kernel")
            ->getEnvironment();
    }

    /**
     * @return string
     */
    protected function getCacheDir()
    {
        return $this
            ->container
            ->get("kernel")
            ->getCacheDir();
    }
}
