<?php

namespace FiloBlu\Esb\Model\Consumer;

use FiloBlu\Esb\Api\Data\MessageInterface;
use FiloBlu\Esb\Core\Exception\NonRecoverableException;
use FiloBlu\Esb\Framework\Template\TemplateInterface;
use RuntimeException;

/**
 *
 * {
 *     "endpoint" : {
 *         "url" : "http://talend.filoblu.com:8088/rest/in/magento/create_order",
 *         "content_type" : "application/json",
 *         "method" : "get",
 *         "timeout" : 30,
 *         "max_redirects" : 1
 *     },
 *     "template_variables" : {
 *         "platform" : "Santoni M2",
 *         "market" : "all",
 *         "channeltype" : "magento"
 *         "body": "##object##"
 *     },
 *     "template_message" : {
 *         "platform" : "#platform#",
 *         "market" : "#market#",
 *         "channeltype" : "#channeltype#",
 *         "message" : "#body#"
 *     },
 *    "on_success_action" : {
 *        "action" : "change_status",
 *        "parameters" : "order_exported"
 *    }
 * }
 *
 * Class SendJsonToEndpointConsumer
 * @package FiloBlu\Esb\Model
 */
abstract class SendObjectToEndpointConsumer extends RestConsumer
{

    /**
     * @param MessageInterface $message
     * @param string $contentType
     * @return string
     * @throws NonRecoverableException|\Magento\Framework\Exception\NoSuchEntityException
     */
    protected function getBody(MessageInterface $message, string $contentType): string
    {
        $object = $this->loadObject($message);

        $objectData = $this->converterResolver->getFor($object)
                                              ->convert($object)
        ;
        $parameters = $this->getConfiguration()
                           ->getParameters()
        ;
        $templateVariables = $parameters->getDataByPath(self::TEMPLATE_VARIABLES) ?? [];
        $templateBody = $parameters->getDataByPath(self::TEMPLATE_BODY) ?? [];

        $switchEvaluator = $this->switchEvaluatorFactory->create();

        foreach ($templateVariables as $name => $value)
        {
            if ($value === self::OBJECT_TAG)
            {
                $templateVariables[$name] = $objectData->getData();
                continue;
            }

            if ($switchEvaluator->is($value))
            {
                $templateVariables[$name] = $switchEvaluator->evaluate(
                    $value,
                    $this->getDataForEvaluation($object)
                );
            }
        }

        /** @var TemplateInterface $template */
        $template = $this->templateFactory->create();
        $body = $template->setVariables($templateVariables)
                         ->setTemplate($templateBody)
                         ->render()
        ;

        // TODO : use an encoder instead
        switch (strtolower($contentType))
        {
            case 'application/json':
                return $body->toJson();
            case 'text/xml':
            case 'application/xml':
                return $body->toXml();
        }

        throw new RuntimeException(__('Unable to encode output for content-type "%1"', $contentType));
    }
}
