<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Auth\Access\AuthorizationException;

class VerifyTenants
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $userRelation
     * @return mixed
     */
    public function handle($request, Closure $next, $userRelation = null)
    {
        $dictionary = [];

        foreach ($request->route()->parameters() as $key => $value) {
            $dictionary[] = ['name' => $key, 'model' => $value];
        }

        for ($i = count($dictionary) - 1; $i > 0; $i--) {
            $this->verifyParentOwnership($dictionary, $i);
        }

        if ($userRelation && count($dictionary) >= 1) {
            $this->verifyUserOwnership($request, $dictionary, $userRelation);
        }

        return $next($request);
    }

    /**
     * Verify that the parent owns the current model.
     *
     * @param  array  $dictionary
     * @param  int  $i
     * @return void
     */
    protected function verifyParentOwnership($dictionary, $i)
    {
        $relation = $dictionary[$i]['model']->{$dictionary[$i - 1]['name']}();

        if ($dictionary[$i - 1]['model']->getKey() !==
            $dictionary[$i]['model']->{$relation->getForeignKey()}) {
            throw new AuthorizationException;
        }
    }

    /**
     * Verify that the user owns the first element in the dictionary.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  array  $dictionary
     * @param  string  $userRelation
     * @return void
     */
    protected function verifyUserOwnership($request, $dictionary, $userRelation)
    {
        $relation = $dictionary[0]['model']->{$userRelation}();

        if ($request->user()->getKey() !==
            $dictionary[0]['model']->{$relation->getForeignKey()}) {
            throw new AuthorizationException;
        }
    }
}
