<?php

/**
 * Lifestyle Webconsulting GmbH
 *
 * LICENSE: This Software is the property of Lifestyle Webconsulting GmbH (Aschaffenburg, Germany)
 * and is private by copyright law - it is NOT Freeware.
 *
 * Any unauthorized use of this software without a valid license
 * is a violation of the license agreement and will be prosecuted by
 * civil and criminal law.
 *
 * @copyright  2018 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 */

namespace Sso\WebserviceBundle\DataFixtures\ORM\Webservice;

use Doctrine\Common\DataFixtures\AbstractFixture;
use Doctrine\Common\DataFixtures\OrderedFixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Sso\WebserviceBundle\Entity\Webservice\Type\Application;
use Sso\WebserviceBundle\Entity\Webservice\Type\Attribute;
use Sso\WebserviceBundle\Entity\Webservice\Type\Role;
use Symfony\Component\Validator\Validator\ValidatorInterface;

/**
 * Class LoadApplications
 * @package Sso\WebserviceBundle\DataFixtures\ORM\Webservice
 */
class LoadApplications extends AbstractFixture implements OrderedFixtureInterface, ContainerAwareInterface
{
    /**
     * @var ContainerInterface
     */
    private $container;

    /**
     * {@inheritDoc}
     */
    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    /**
     * Creates applications
     * - TestApp1 (RefId: application-TestApp1)
     * - TestApp2 (RefId: application-TestApp2)
     * - WebserviceConsumer (RefId: application-WebserviceConsumer)
     *
     * Attributes and roles also have reference ids: e. g.
     * - application-TestApp1-attribute-TestAttribute1 or
     * - application-WebserviceConsumer-role-MyNewAppName:read
     *
     * @param ObjectManager $manager
     */
    public function load(ObjectManager $manager)
    {
        $data = array(
            // Application
            array('TestApp1', 'For testing', array(
                    // Attributes
                    array('TestAttribute1', 'one'),
                    array('TestAttribute2', 'many')
                ), array(
                    // Roles
                    array('TestRole1', 'For testing'),
                    array('TestRole2', 'For testing')
                )),
            // Application
            array('TestApp2', 'For testing', array(
                    // Attributes
                ), array(
                    // Roles
                )),
            array('WebserviceConsumer', 'For testing', array(
                    // Attributes
                    array('UserWS-ServiceToken', 'many')
                ), array(
                    // Roles
                    array('WebserviceConsumer:read', 'For testing'),
                    array('WebserviceConsumer:write', 'For testing'),
                    array('MyNewAppName:read', 'For testing'),
                    array('MyNewAppName:write', 'For testing'),
                ))
        );
        $this->loadApplications($manager, $data);
    }

    /**
     * @param ObjectManager $manager
     * @param array $rows
     */
    private function loadApplications(ObjectManager $manager, array $rows)
    {
        foreach ($rows as $row) {
            $entity = new Application($this->getValidator());
            $entity->setName($row[0])
                    ->setDescription($row[1])
                    ->generateId();
            $manager->persist($entity);
            $this->loadApplicationAttributes($manager, $row[2], $entity);
            $this->loadApplicationRoles($manager, $row[3], $entity);

            $this->addReference('application-' . $entity->getName(), $entity);
        }
        $manager->flush();
    }

    /**
     * @param ObjectManager $manager
     * @param array $rows
     * @param Application $application
     */
    private function loadApplicationAttributes(ObjectManager $manager, array $rows, Application $application)
    {
        foreach ($rows as $row) {
            $entity = new Attribute($this->getValidator());
            $entity->setName($row[0])
                    ->setType($row[1])
                    ->setApplication($application)
                    ->generateId();
            $manager->persist($entity);

            $this->addReference('application-' . $application->getName() . '-attribute-' . $entity->getName(), $entity);
        }
    }

    /**
     * @param ObjectManager $manager
     * @param array $rows
     * @param Application $application
     */
    private function loadApplicationRoles(ObjectManager $manager, array $rows, Application $application)
    {
        foreach ($rows as $row) {
            $entity = new Role($this->getValidator());
            $entity->setName($row[0])
                    ->setDescription($row[1])
                    ->setApplication($application)
                    ->generateId();
            $manager->persist($entity);

            $this->addReference('application-' . $application->getName() . '-role-' . $entity->getName(), $entity);
        }
    }

    /**
     * @return ValidatorInterface
     */
    private function getValidator()
    {
        return $this->container->get('validator');
    }

    /**
     * {@inheritDoc}
     */
    public function getOrder()
    {
        return 1;
    }
}
