<?php
/**
 * Copyright 2016 David Vivier on behalf of Smartic.ca
 * 
 * This file is part of the Smarticops Package
 * 
 * License : MIT
 * 
 * @author David Vivier
 */

namespace Dvivier\Smarticops\Http\Controllers;

use Illuminate\Http\Request;

use Dvivier\Smarticops\Http\Requests;

use Session;
use Validator;

use Dvivier\Smarticops\Role;
use Dvivier\Smarticops\Permission;

use Dvivier\Smarticops\Facades\Smarticops;

/**
 * The controller for the Dvivier\Smarticops\Roles model.
 * 
 */
class RolesController extends Controller
{
    
    /**
     * The roles index.
     * 
     * @todo pagination
     * @todo sorting
    */
    public function index() {
        
        $roles = Role::all();
        
        return view('smarticops::roles.index', compact('roles'));
    }
    
    /**
     * Prepare the view to create a role
     * 
     */
    public function create() {
        
        $updating = false;
        /*$permissions = Permission::all()
                                        ->reject(function($perm) {
                                            // "sa" permission - not visible
                                            return ($perm->id === 1);
                                        });*/
        $permissions = Permission::all();
        $permissions->shift();
        return view('smarticops::roles.edit', compact('updating', 'permissions'));
    }
    
    /**
     * Prepare view to edit an existing role
     * 
     * @param  Role  $role
     */
    public function edit(Role $role) {
        $updating = true;
        /*$permissions = Permission::all()
                                        ->reject(function($perm) {
                                            // "sa" permission - not visible
                                            return ($perm->id === 1);
                                        });*/
        $permissions = Permission::all();
        $permissions->shift();
        return view('smarticops::roles.edit', compact('updating', 'permissions', 'role'));
    }
    
    /**
     * Handles a create request, then calls general post() method
     * 
     * @param  Request  $request
     * 
     * @see RolesController::post() post()
     */
    public function create_post(Request $request) {
        /*
        $this->validate($request, [
                                    'name' => [
                                                'required',
                                                // special characters will mess with the javascript function names
                                                'regex:/^[a-zA-Z0-9_]*$/',
                                                'unique:roles,name,NULL,id,deleted_at,NULL',
                                                ]
                                    //'description' => 'required',
                                    ]);*/
        $rules = [
                    'name' => [
                                'required',
                                // special characters will mess with the javascript function names
                                'regex:/^[a-zA-Z0-9_]*$/',
                                'unique:roles,name,NULL,id,deleted_at,NULL',
                                ]
                    ];
                    
        $messages = [
                        'required'      => trans('smarticops::validation.required'),
                        
                        'unique'   => trans('smarticops::validation.custom.name.unique'),
                        'regex'    => trans('smarticops::validation.custom.name.regex'),
                        ];
                        
        $validator = Validator::make($request->all(), $rules, $messages);
        
        if ($validator->fails()) {
            return redirect('roles/create')->withErrors($validator)->withInput();
        }
        
        $role = new Role;
        return $this->post($request, $role, false);
    }
    
    /**
     * Handles an edit request, then calls general post() method
     * 
     * @param  Request  $request
     * @param  Role  $role
     * 
     * @see RolesController::post() post()
     */
    public function edit_post(Request $request, Role $role) {
        /*
        $this->validate($request, [
                                    'name' => [
                                                'required',
                                                'regex:/^[a-zA-Z0-9_]*$/',
                                                'unique:roles,name,'.$role->id.',id,deleted_at,NULL',
                                                ],
                                    //'description' => 'required',
                                    ]);*/
        $rules = [
                    'name' => [
                                'required',
                                // special characters will mess with the javascript function names
                                'regex:/^[a-zA-Z0-9_]*$/',
                                'unique:roles,name,'.$role->id.',id,deleted_at,NULL',
                                ]
                    ];
                    
        $messages = [
                        'required'      => trans('smarticops::validation.required'),
                        'unique'   => trans('smarticops::validation.custom.name.unique'),
                        'regex'    => trans('smarticops::validation.custom.name.regex'),
                        ];
                        
        $validator = Validator::make($request->all(), $rules, $messages);
        
        if ($validator->fails()) {
            return redirect('roles/edit/'.$role->id)->withErrors($validator)->withInput();
        }
        
        return $this->post($request, $role, true);
    }
    
    /**
     * Called when creating and updating a role
     * 
     * @param  Request  $request
     * @param  Role  $role  The role, already existing or freshly created
     * @param  boolean  $updating Whether it's an update (true) or the creation (false) of the role.
     */ 
    public function post($request, $role, $updating = false) {
        
        $old = clone $role;
        
        $role->name = $request->name;
        $role->description = $request->description;
        
        $role->save();
        
        $permissions = $request->codes;
        
        $role->removeAllPermissions();
        
        if(count($permissions) > 0) {
            foreach($permissions as $permission) {
                $role->givePermission($permission);
            }
        }
        
        $res = $role->save();
        
        if ($updating) {
            if ($res) {
                Session::flash('info', trans('smarticops::roles.info.updated', ['name' => $role->name]));
            } else {
                Session::flash('info', trans('smarticops::roles.error.updating'));
            }
            Smarticops::logRoleUpdated($role, $old, $res);
        } else {
            if ($res) {
                Session::flash('info', trans('smarticops::roles.info.created', ['name' => $role->name]));
            } else {
                Session::flash('info', trans('smarticops::roles.error.creating'));
            }
            Smarticops::logRoleCreated($role, $res);
        }
        
        return redirect('/roles');
    }
    
    /**
     * Handles a delete request
     * 
     * @param  Role  $role
     */
    public function delete(Role $role) {
        
        if (null === $role) {
            Session::flash('info', trans('smarticops::roles.error.deleting'));
            return redirect('/roles');
        }
        
        if (count($role->users) > 0) {
            Session::flash('info', trans_choice('smarticops::roles.list.nodelete', 
                                                                count($role->users), 
                                                                [    'n_users' => count($role->users),
                                                            ]));
            return redirect('/roles');
        }
        
        $res = $role->delete();
        
        if ($res) {
            Session::flash('info', trans('smarticops::roles.info.deleted', ['name' => $role->name]));
        } else {
            Session::flash('info', trans('smarticops::roles.error.deleting'));
        }
        Smarticops::logRoleDeleted($role, $res);
        return redirect('/roles');
    }
}

