<?php
/**
 * This file is part of the DATAtourisme project.
 *
 *  @author Conjecto <contact@conjecto.com>
 *
 * For the full copyright and license information, please view the LICENSE file that was distributed with this source code.
 */

namespace Datatourisme\Api\Resolver\SparqlResolver\QueryBuilder;

use Datatourisme\Api\Resolver\SparqlResolver\Sparql\Triplet;
use Datatourisme\Api\Resolver\SparqlResolver\Utils\SparqlUtils;
use Youshido\GraphQL\Type\AbstractType;

class SortGenerator
{
    /**
     * @param $subject
     * @param $arguments
     * @param AbstractType $outputTypeDef
     *
     * @return \Datatourisme\Api\Resolver\SparqlResolver\QueryBuilder\OrderClause
     *
     * @throws \Exception
     */
    public function getSort($subject, $arguments, AbstractType $outputTypeDef)
    {
        $sorts = (isset($arguments['sort'])) ? $arguments['sort'] : [];
        if (count($sorts) && !isset($sorts[0])) {
            throw new \Exception(json_encode(['First argument of sort must be an array']));
        }

        $orderClause = new OrderClause();
        //$orderClause->getPatterns()->add(new Triplet($subject, 'a', '<'.$outputTypeDef->getUri().'>'));

        $recursiveBuild = function ($subject, $type, $sort) use ($orderClause, &$recursiveBuild) {
            $key = key($sort);
            $value = @reset($sort);
            if ('order' == $key) {
                $orderClause->getConditions()->add(strtoupper($value).'('.$subject.')');
            } else {
                $field = $type->getField($key);
                $object = SparqlUtils::uniqVariable($subject, $field->getUri());
                $orderClause->getPatterns()->add(new Triplet($subject, '<'.$field->getUri().'>', $object));
                $recursiveBuild($object, $field->getType()->getItemType(), $value);
            }
        };

        foreach ($sorts as $sort) {
            $recursiveBuild($subject, $outputTypeDef, $sort);
        }

        $orderClause->getConditions()->add('?res');

        return $orderClause;
    }
}
