<?php

namespace Anax\DI;

/**
 * Interface to implement for DI aware services to let them know of the current $di
 *
 */
trait TInjectable
{

    /**
     * Properties
     */
    protected $di; // the service container



    /**
     * Set the service container to use
     *
     * @param class $di a service container
     *
     * @return $this
     */
    public function setDI($di)
    {
        $this->di = $di;
    }



    /**
     * Magic method to get and create services.
     * When created it is also stored as a parameter of this object.
     *
     * @param string $service name of class property not existing.
     *
     * @return class as the service requested.
     */
    public function __get($service)
    {
        if (!$this->di) {
            throw new \Exception(
                'In trait TInjectable used by class ' . __CLASS__ . '. You are trying to get
                message, code a property from $this->di, but $this->di is not set. Did you
                forget to call setDI()?'
            );
        }

        try {

            $this->$service = $this->di->get($service);
            return $this->$service;

        } catch (\Exception $e) {
            throw new \Exception(
                'In trait TInjectable used by class ' . __CLASS__ . '. You are trying to get
                a property (service) "' . $service . '" from $this->di, but the service is not
                set in $this->di. Did you misspell the service you are trying to reach or did
                you forget to load it into the $di container?'
                . $e->getMessage()
            );
        }
    }



   /**
     * Magic method to get and create services as a method call.
     * When created it is also stored as a parameter of this object.
     *
     * @param string $service   name of class property not existing.
     * @param array  $arguments Additional arguments to sen to the method (NOT IMPLEMENTED).
     *
     * @return class as the service requested.
     */
    public function __call($service, $arguments = [])
    {
        if (!$this->di) {
            throw new \Exception(
                'In trait TInjectable used by class ' . __CLASS__ . '. You are trying to call a
                method in $this->di, but $this->di is not set. Did you forget to call setDI()?'
            );
        }

        try {

            $this->$service = $this->di->get($service);
            return $this->$service;

        } catch (\Exception $e) {
            throw new \Exception(
                'In trait TInjectable used by class ' . __CLASS__ . '. You are trying to get a
                method (service) "' . $service . '" from $this->di, but the service is not set
                in $this->di. Did you misspell the service you are trying to reach or did you
                forget to load it into the $di container? '
                . $e->getMessage()
            );
        }
    }
}

