<?php

namespace PeytzMail\Entity;

use PeytzMail\Exception\InvalidArgumentException;

/**
 * @package PeytzMail
 */
abstract class AbstractEntity
{
    /**
     * Set not existing property in user's given case.
     *
     * @param string $property
     * @param mixed  $value
     */
    public function __set($property, $value)
    {
        $this->$property = $value;
    }

    /**
     * Return only existing or defined property's value.
     *
     * @param  string                   $property
     * @throws InvalidArgumentException
     * @return mixed
     */
    public function __get($property)
    {
        if (property_exists($this, $property)) {
            return $this->$property;
        }

        throw new InvalidArgumentException(sprintf(
            '[Peytz Mail] Property "%s::%s" does not exist.', get_class($this), $property)
        );
    }

    /**
     * Set property in camelCase.
     *
     * @param string $property
     * @param mixed  $value
     */
    public function setInCamelCase($property, $value)
    {
        $this->{convert_to_camel_case($property)} = $value;
    }

    /**
     * Build the entity with given parameters.
     *
     * @param \stdClass|array $parameters
     */
    public function build($parameters)
    {
        foreach ($parameters as $property => $value) {
            $this->setInCamelCase($property, $value);
        }
    }

    /**
     * Transform all object's properties in underscore_case.
     * This method is used when the entity should be posted to Peytz Mail.
     */
    public function prepare()
    {
        $properties = get_object_vars($this);

        foreach ($properties as $property => $value) {
            if (property_exists($this, $snakeCased = convert_to_snake_case($property))) {
                continue;
            }

            $this->$snakeCased = $value;
            unset($this->$property);
        }
    }
}
