<?php

namespace FR\V1_0\Entities\RemoteHub;

use FR\Interfaces\RemoteHubInterface;
use FR\Interfaces\TransportInterface;
use FR\Traits\FromArray;

/**
 * Class RemoteHub
 * @package FR\V1_0\Entities
 */
class RemoteHub implements RemoteHubInterface
{
    use FromArray;
    public const FEEDER_ROLE = 'feeder';
    public const SUPERHUB_ROLE = 'superhub';

    public const TARGET_STATE_ON = 'on';
    public const TARGET_STATE_PAUSED = 'paused';
    public const TARGET_STATE_OFF = 'off';

    /**
     * @var array
     */
    public static $allowedRoles = [self::FEEDER_ROLE, self::SUPERHUB_ROLE];

    /**
     * @var array
     */
    public static $allowedStates = [self::TARGET_STATE_ON, self::TARGET_STATE_PAUSED, self::TARGET_STATE_OFF];

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

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

    /**
     * @var int
     */
    private $id;

    /**
     * @var string
     */
    private $hostkey;
    /**
     * @var bool
     */
    private $enabled;
    /**
     * @var string
     */
    private $role;

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

    /**
     * @var TransportInterface
     */
    private $transport;

    /**
     * @var array
     */
    private $statistics = [];

    /**
     * Validate remote hub entity
     */
    public function validate()
    {
        $errors = [];

        if (empty($this->ui_name)) {
            $errors[] = '`ui_name` is required argument';
        }

        if (empty($this->role)) {
            $errors[] = '`role` is required argument';
        } elseif (!in_array($this->role, self::$allowedRoles)) {
            $errors[] = 'Wrong `role` value. Allowed values: ' . implode(', ', self::$allowedRoles);
        }

        if (!isset($this->target_state) || empty($this->target_state)) {
            $errors[] = '`target_state` is required argument';
        } elseif (!in_array($this->target_state, self::$allowedStates)) {
            $errors[] = 'Wrong `target_state` value. Allowed values: ' . implode(', ', self::$allowedStates);
        }

        if (empty($this->transport)) {
            $errors[] = '`transport` is required argument';
        }

        if (sizeof($errors) > 0) {
            throw new \ResponseException(implode(PHP_EOL, $errors), \Response::BADREQUEST);
        }
    }

    /**
     * @return array
     */
    public function toArray()
    {
        return [
            'id' => $this->getId(),
            'hostkey' => $this->getHostKey(),
            'api_url' => $this->getApiUrl(),
            'ui_name' => $this->getUiName(),
            'role' => $this->getRole(),
            'target_state' => $this->getTargetState(),
            'transport' => $this->getTransport()->toArray(),
            'statistics' => $this->getStatistics()
        ];
    }

    /**
     * @return int|null
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * @param $id
     *
     */
    public function setId($id)
    {
        $this->id = $id;
    }

    /**
     * @return string
     */
    public function getHostKey(): string
    {
        return !empty($this->hostkey) ? $this->hostkey : '';
    }

    /**
     * @param string $hostkey
     */
    public function setHostKey($hostkey)
    {
        $this->hostkey = $hostkey;
    }

    /**
     * @return string
     */
    public function getUiName(): string
    {
        return $this->ui_name;
    }

    /**
     * @param string $uiName
     */
    public function setUiName($uiName)
    {
        $this->ui_name = $uiName;
    }

    /**
     * @return string
     */
    public function getRole(): string
    {
        return $this->role;
    }

    /**
     * @param string $role
     */
    public function setRole($role)
    {
        $this->role = $role;
    }


    /**
     * @return int|null|string
     */
    public function getTargetState()
    {
        return $this->target_state;
    }

    /**
     * @param $state
     */
    public function setTargetState($state)
    {
        $this->target_state = $state;
    }

    /**
     * @return TransportInterface
     */
    public function getTransport(): TransportInterface
    {
        return $this->transport;
    }

    /**
     * @param TransportInterface $transport
     */
    public function setTransport(TransportInterface $transport)
    {
        $this->transport = $transport;
    }

    /**
     * @return string
     */
    public function getApiUrl(): string
    {
        return $this->api_url !== null ? $this->api_url : '';
    }

    /**
     * @param string $api_url
     */
    public function setApiUrl($api_url)
    {
        $this->api_url = $api_url;
    }

    /**
     * @return string
     */
    public function getStatistics(): array
    {
        return (array) $this->statistics;
    }

    /**
     * @param array $statistics
     */
    public function setStatistics($statistics)
    {
        $this->statistics = $statistics;
    }

    /**
     * @return mixed|void
     */
    public function jsonSerialize()
    {
        return $this->toArray();
    }
}
