<?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\Entity\Webservice\Type;

use Doctrine\Common\Collections\ArrayCollection;
use Symfony\Component\Validator\Validator\ValidatorInterface as Validator;
use Sso\WebserviceBundle\Api\Exception\Type\Api as ApiException;

/**
 * Class Attribute
 *
 * @copyright  2017 Lifestyle Webconsulting GmbH
 * @link       http://www.life-style.de
 * @package Sso\WebserviceBundle\Entity\Webservice\Type
 */
class Attribute extends Base implements AttributeInterface
{
    /**
     * @var string
     */
    private $Id;

    /**
     * @var string
     */
    private $Name;

    /**
     * @var string
     */
    private $Lowername;

    /**
     * @var string
     */
    private $Type;

    /**
     * @var string|null
     */
    private $displayType;

    /**
     * @var array|null
     */
    private $attributeOptions;

    /**
     * @var Application
     */
    private $Application;

    /**
     * @var ArrayCollection|UserApplicationAttribute[]
     */
    private $UserApplicationAttributes;

    /**
     * Constructor
     *
     * @param Validator $validator
     */
    public function __construct(Validator $validator)
    {
        parent::__construct($validator);
        $this->UserApplicationAttributes = new ArrayCollection();
    }

    /**
     * Initialize object with new values
     *
     * @param array|object $values
     * @param array|null $validationGroups Null for full validation, array of group-name(s) for group specific validation
     */
    public function init($values, $validationGroups = null)
    {
        // Generate new attribute-id
        $this->generateId();

        parent::init($values, $validationGroups);
    }

    /**
     * Generate unique attribute id
     *
     * @return string
     * @throws ApiException
     */
    public function generateId()
    {
        if (null !== $this->Id) {
            throw new ApiException('Changing the application-attribute-id is not allowed!');
        }
        return $this->Id = hash('sha256', mt_rand() . '#' . microtime());
    }

    /**
     * Get Id
     *
     * @return string
     */
    public function getId()
    {
        return $this->Id;
    }

    /**
     * Set Id
     *
     * @param string $id
     * @return Attribute
     */
    public function setId($id)
    {
        $this->Id = $id;

        return $this;
    }

    /**
     * Get Name
     *
     * @return string
     */
    public function getName(): string
    {
        return (string)$this->Name;
    }

    /**
     * Set Name
     *
     * @param string $name
     * @return Attribute
     */
    public function setName($name)
    {
        $this->Name = $name;
        $this->Lowername = strtolower($name);

        return $this;
    }

    /**
     * Get Lowername
     *
     * @return string
     */
    public function getLowername()
    {
        return $this->Lowername;
    }

    /**
     * Returns true, if attribute is multi value
     *
     * @return bool
     */
    public function isArray()
    {
        return $this->Type === 'many';
    }

    /**
     * Get Type
     *
     * @return string
     */
    public function getType()
    {
        return $this->Type;
    }

    /**
     * Set Type
     *
     * @param string $type
     * @return Attribute
     */
    public function setType($type)
    {
        $this->Type = $type;

        return $this;
    }

    /**
     * @return string|null
     */
    public function getDisplayType(): ?string
    {
        return $this->displayType;
    }

    /**
     * @param string|null $displayType
     */
    public function setDisplayType(?string $displayType): void
    {
        $this->displayType = $displayType;
    }

    /**
     * @return array|null
     */
    public function getAttributeOptions(): ?array
    {
        return $this->attributeOptions;
    }

    /**
     * @param array|null $attributeOptions
     */
    public function setAttributeOptions(?array $attributeOptions): void
    {
        $this->attributeOptions = [];
        foreach ($attributeOptions ?? [] as $label => $value) {
            $this->addAttributeOption($label, $value);
        }
        if (0 === count($this->attributeOptions)) {
            $this->attributeOptions = null;
        }
    }

    /**
     * @param string $label
     * @param string $value
     */
    public function addAttributeOption(string $label, string $value)
    {
        $this->attributeOptions[$label] = $value;
    }

    /**
     * Get Application
     *
     * @return Application
     */
    public function getApplication()
    {
        return $this->Application;
    }

    /**
     * Set Application
     *
     * @param Application $Application
     * @return Attribute
     */
    public function setApplication(Application $Application = null)
    {
        $this->Application = $Application;

        return $this;
    }

    /**
     * Add UserApplicationAttribute
     *
     * @param UserApplicationAttribute $userApplicationAttribute
     * @return Attribute
     */
    public function addUserApplicationAttribute(UserApplicationAttribute $userApplicationAttribute)
    {
        $this->UserApplicationAttributes[] = $userApplicationAttribute;

        return $this;
    }

    /**
     * Remove UserApplicationAttribute
     *
     * @param UserApplicationAttribute $userApplicationAttribute
     */
    public function removeUserApplicationAttribute(UserApplicationAttribute $userApplicationAttribute)
    {
        $this->UserApplicationAttributes->removeElement($userApplicationAttribute);
    }

    /**
     * lifecycleCallbacks PrePersist
     */
    public function onPrePersist()
    {
        foreach ($this->getUserApplicationAttributes() as $userApplicationAttribute) {
//            $userApplicationAttribute->getUserApplication()->getUser()->setUpdatedReferencesAt(new \DateTime());
            break;
        }
    }

    /**
     * Get UserApplicationAttributes
     *
     * @return ArrayCollection|UserApplicationAttribute[]
     */
    public function getUserApplicationAttributes()
    {
        return $this->UserApplicationAttributes;
    }

    /**
     * lifecycleCallbacks PreUpdate
     */
    public function onPreUpdate()
    {
        foreach ($this->getUserApplicationAttributes() as $userApplicationAttribute) {
//            $userApplicationAttribute->getUserApplication()->getUser()->setUpdatedReferencesAt(new \DateTime());
            break;
        }
    }

    /**
     * lifecycleCallbacks PreRemove
     */
    public function onPreRemove()
    {
        foreach ($this->getUserApplicationAttributes() as $userApplicationAttribute) {
//            $userApplicationAttribute->getUserApplication()->getUser()->setUpdatedReferencesAt(new \DateTime());
            break;
        }
    }
}
