<?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\Providers;

use Illuminate\Support\ServiceProvider;

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

use Log;
use Config;
use Auth;

/** 
 * The service provider which initializes Smarticops.
 * 
 */
class SmarticopsServiceProvider extends ServiceProvider
{
     
    /**
     * Perform post-registration booting of services.
     *
     * @return void
     */
    public function boot()
    {
        
        /// Package
        
        // config file
        $this->publishes([ __DIR__.'/../config/smarticops.php' => config_path('smarticops.php')], 'config');
        
        
        // routes
        if ( ! $this->app->routesAreCached()) {
            require __DIR__.'/../Http/routes.php';
        }
        
        // Administrator middleware
        $this->app['router']->middleware('admin', \Dvivier\Smarticops\Http\Middleware\SmarticopsAdministrator::class);
        
        
        // views
        $this->loadViewsFrom(__DIR__.'/../resources/views', 'smarticops');
        
        $this->publishes([__DIR__.'/../resources/views' => resource_path('views/vendor/smarticops')]);
        
        // lang
        $this->loadTranslationsFrom(__DIR__.'/../resources/lang', 'smarticops');
        
        $this->publishes([__DIR__.'/../resources/lang' => resource_path('lang/vendor/smarticops')]);
        
        // migrations and seeding
        $this->publishes([
                            __DIR__.'/../database/migrations'   => database_path('migrations'),
                            __DIR__.'/../database/seeds'         => database_path('seeds'),
                            __DIR__.'/../database/factories'    => database_path('factories'),
                        ], 'database');

        
        /// -------------------
        /// Event registering
        
        // User
        
        User::creating( function( $user )  {
            $user->uuid = self::uuidv4();
            if (Auth::check()) {
                $id = Auth::user()->id;
                $user->created_by = $id;
            }
        });
        
        User::updating( function($user) {
            if (Auth::check()) {
                $id = Auth::user()->id;
                $user->updated_by = $id;
            }
        });
        
        User::deleting(function($user) {
            if (Auth::check()) {
                $id = Auth::user()->id;
                $user->deleted_by = $id;
            }
        });
        
        
        // Role
        
        Role::creating( function( $role )  {
            $role->uuid = self::uuidv4();
            if (Auth::check()) {
                $id = Auth::user()->id;
                $role->created_by = $id;
            }
        });
        
        Role::updating( function($role) {
            if (Auth::check()) {
                $id = Auth::user()->id;
                $role->updated_by = $id;
            }
        });
        
        Role::deleting(function($role) {
            if (Auth::check()) {
                $id = Auth::user()->id;
                $role->deleted_by = $id;
            }
        });
        
        
        // Permission
        
        Permission::creating( function( $permission )  {
            $permission->uuid = self::uuidv4();
            if (Auth::check()) {
                $id = Auth::user()->id;
                $permission->created_by = $id;
            }
        });
        
        Permission::updating( function($permission) {
            if (Auth::check()) {
                $id = Auth::user()->id;
                $permission->updated_by = $id;
            }
        });
        
        Permission::deleting(function($permission) {
            if (Auth::check()) {
                $id = Auth::user()->id;
                $permission->deleted_by = $id;
            }
        });

        Log::useDailyFiles(storage_path().'/'.Config::get('smarticops.log_path', 'logs/smarticops/smarticops'));

    }

    /**
     * Register any package services.
     *
     * @return void
     */
    public function register()
    {
        // registers the setup command
        $this->commands('Dvivier\Smarticops\Console\Commands\SmarticopsSetupCommand');
    }
    
    
    /**
     * Generates a version 4 UUID.
     * 
     * @see  https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_.28random.29  Wikipedia UUID Article
     * @see  http://stackoverflow.com/a/2040279/6161127  Stackoverflow Answer
     * @see  http://php.net/manual/en/function.uniqid.php#94959  Comment on PHP manual
     */
    public static function uuidv4() {
        return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        
        // 32 bits for "time_low"
        mt_rand(0, 0xffff), mt_rand(0, 0xffff),
        
        // 16 bits for "time_mid"
        mt_rand(0, 0xffff),
        
        // 16 bits for "time_hi_and_version",
        // four most significant bits holds version number 4
        mt_rand(0, 0x0fff) | 0x4000,
        
        // 16 bits, 8 bits for "clk_seq_hi_res",
        // 8 bits for "clk_seq_low",
        // two most significant bits holds zero and one for variant DCE1.1
        mt_rand(0, 0x3fff) | 0x8000,
        
        // 48 bits for "node"
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
        );
    }
}
