<?php

namespace Modular\ConnectorDependencies\Illuminate\Routing;

use Modular\ConnectorDependencies\Illuminate\Contracts\Routing\UrlRoutable;
use Modular\ConnectorDependencies\Illuminate\Database\Eloquent\ModelNotFoundException;
use Modular\ConnectorDependencies\Illuminate\Database\Eloquent\SoftDeletes;
use Modular\ConnectorDependencies\Illuminate\Support\Reflector;
use Modular\ConnectorDependencies\Illuminate\Support\Str;
class ImplicitRouteBinding
{
    /**
     * Resolve the implicit route bindings for the given route.
     *
     * @param  \Illuminate\Container\Container  $container
     * @param  \Illuminate\Routing\Route  $route
     * @return void
     *
     * @throws \Illuminate\Database\Eloquent\ModelNotFoundException
     */
    public static function resolveForRoute($container, $route)
    {
        $parameters = $route->parameters();
        foreach ($route->signatureParameters(UrlRoutable::class) as $parameter) {
            if (!$parameterName = static::getParameterName($parameter->getName(), $parameters)) {
                continue;
            }
            $parameterValue = $parameters[$parameterName];
            if ($parameterValue instanceof UrlRoutable) {
                continue;
            }
            $instance = $container->make(Reflector::getParameterClassName($parameter));
            $parent = $route->parentOfParameter($parameterName);
            $routeBindingMethod = $route->allowsTrashedBindings() && in_array(SoftDeletes::class, \Modular\ConnectorDependencies\class_uses_recursive($instance)) ? 'resolveSoftDeletableRouteBinding' : 'resolveRouteBinding';
            if ($parent instanceof UrlRoutable && ($route->enforcesScopedBindings() || array_key_exists($parameterName, $route->bindingFields()))) {
                $childRouteBindingMethod = $route->allowsTrashedBindings() && in_array(SoftDeletes::class, \Modular\ConnectorDependencies\class_uses_recursive($instance)) ? 'resolveSoftDeletableChildRouteBinding' : 'resolveChildRouteBinding';
                if (!$model = $parent->{$childRouteBindingMethod}($parameterName, $parameterValue, $route->bindingFieldFor($parameterName))) {
                    throw (new ModelNotFoundException())->setModel(get_class($instance), [$parameterValue]);
                }
            } elseif (!$model = $instance->{$routeBindingMethod}($parameterValue, $route->bindingFieldFor($parameterName))) {
                throw (new ModelNotFoundException())->setModel(get_class($instance), [$parameterValue]);
            }
            $route->setParameter($parameterName, $model);
        }
    }
    /**
     * Return the parameter name if it exists in the given parameters.
     *
     * @param  string  $name
     * @param  array  $parameters
     * @return string|null
     */
    protected static function getParameterName($name, $parameters)
    {
        if (array_key_exists($name, $parameters)) {
            return $name;
        }
        if (array_key_exists($snakedName = Str::snake($name), $parameters)) {
            return $snakedName;
        }
    }
}
