<?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\Console\Commands;

use Illuminate\Console\Command;

/**
 * Setup the Smarticops package by doing operations automatically instead of manually
 * 
 */
class SmarticopsSetupCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'smarticops:setup';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Smarticops Setup';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        
        $this->info('Welcome to the Smarticops\'s setup process.');
        
        // make sure the user knows what he's doing
        do {
            $this->line('Please read the README.md file, especially concerning the SuperAdmin.');
        } while(!$this->confirm('Did you read the dvivier/smarticops/README.md file ?'));
        
        $password_minimum = 8;
        
        // Ask for the SuperAdmin data
        
        do {
            $app_name = $this->ask('Your Application\'s name ');
            $first_name = $this->ask('SuperAdmin first name ');
            $last_name = $this->ask('SuperAdmin last name ');
            $email = $this->ask('SuperAdmin email ');
            
            $this->line('password must be at least '.$password_minimum.' characters long.');
            
            $password = $password_confirmation = '';
            do {
                $password = $this->secret('SuperAdmin password ');
                $password_confirmation = $this->secret('Confirm password ');
                if ($password != $password_confirmation) {
                    $this->error('Passwords does not match.');
                }
                if (strlen($password) < $password_minimum) {
                    $this->error('password must be at least '.$password_minimum.' characters long.');
                }
            } while ($password != $password_confirmation or strlen($password) < 8);
            
            $this->line('You can change the SuperAdmin password later in the .env file.');

            $this->line('');
            $this->line('| Application name is '.$app_name);
            $this->line('| SuperAdmin is '.$first_name.' '.$last_name.' <'.$email.'>');
        } while ( ! $this->confirm('Is this information correct ?'));
        
        // add configuration at the end of the .env file with the provided data
        file_put_contents($this->laravel->environmentFilePath(),
                            "\n\n".
                            "\nAPP_NAME='$app_name'".
                            "\n".
                            "\nSUPERADMIN_FIRSTNAME='$first_name'".
                            "\nSUPERADMIN_LASTNAME='$last_name'".
                            "\nSUPERADMIN_EMAIL='$email'".
                            "\nSUPERADMIN_PASSWORD='$password'",
                            
                            FILE_APPEND );
        $this->info('Information saved in the .env file');
        
        $this->info('Publishing views, migrations, seeds, configuration and translations...');
        $this->line('php artisan vendor:publish');
        $this->call('vendor:publish');
        
        // make sure the database is ready
        do {
            $this->line('');
            $this->line('Smarticops is now about to create tables and insert data.');
            $this->line('You must have set the database settings in your .env file.');
            $this->line('Make sure that the database server is running and that you have setup the database access correctly.');
        } while( ! $this->confirm('Did you configure the database ? [y|n]'));
        
        
        $this->info('Removing unused migrations...');
        // those migrations are not used since they are replaced by smarticops' ones
        $this->line('rm -v database/migrations/2014_10_12_000000_create_users_table.php');
        exec('rm -v database/migrations/2014_10_12_000000_create_users_table.php');
        $this->line('rm -v database/migrations/2014_10_12_100000_create_password_resets_table.php');
        exec('rm -v database/migrations/2014_10_12_100000_create_password_resets_table.php');
        
        // The SmarticopsSeeder has to be called by the default DatabaseSeeder
        $this->info('Adding SmarticopsSeeder to default seeder...');
            file_put_contents(database_path('seeds/DatabaseSeeder.php'), str_replace(
                '        // $this->call(UsersTableSeeder::class);',
                '        // automatically generated by '.$this->signature.' command from Smarticops package'.
                "\n".
                '        $this->call(SmarticopsSeeder::class);',
                file_get_contents(database_path('seeds/DatabaseSeeder.php'))
            ));
        
        
        // necessary for the SmarticopsSeeder to be found
        $this->info('Updating Composer autoload...');
        $this->line('composer dump-autoload');
        exec('composer dump-autoload');
        
        
        $this->info('Migrating and seeding database...');
            $this->line('php artisan migrate:refresh --seed');
            $this->call('migrate:refresh', [
                                             '--seed' => true,
                                             ]);
        
        
        // The User class has to extend Smarticops\User
        $this->info('Updating App\User class...');
    
            file_put_contents(app_path('User.php'), str_replace(
                'class User extends Authenticatable',
                "use Dvivier\Smarticops\User as SmarticopsUser;".
                "\n".
                "\n".
                "// class declaration was automatically modified by '.$this->signature.' command from Smarticops package".
                "\n".
                "class User extends SmarticopsUser",
                file_get_contents(app_path('User.php'))
            ));
            
            
        // `Form` and `Html` components from the Laravel Collective community organisation are needed for forms in the administration panel.

        $this->info('Adding Service Providers in config/app.php...');
            
            // service providers
            file_put_contents(config_path('app.php'), str_replace(
                '        App\Providers\RouteServiceProvider::class,',
                '        App\Providers\RouteServiceProvider::class,'."\n".
                "\n".
                '        // automatically generated by '.$this->signature.' command from Smarticops package'."\n".
                '        Collective\Html\HtmlServiceProvider::class,'."\n".
                "\n".
                                    //      not generated because it has to be written by the package user before using the command
                //'        Dvivier\Smarticops\Providers\SmarticopsServiceProvider::class,'."\n" 
                
                "\n",
                
                file_get_contents(config_path('app.php'))
            ));
            
                // `Form` and `Html` components from the Laravel Collective community organisation are needed for forms in the administration panel.
            
            // aliases 
            file_put_contents(config_path('app.php'), str_replace(
                '        \'View\' => Illuminate\Support\Facades\View::class,',
                '        \'View\' => Illuminate\Support\Facades\View::class,'."\n".
                "\n".
                '        // automatically generated by '.$this->signature.' command from Smarticops package'."\n".
                '        \'Form\' => Collective\Html\FormFacade::class,'."\n".
                '        \'Html\' => Collective\Html\HtmlFacade::class,'."\n".
                "\n",
                
                file_get_contents(config_path('app.php'))
            ));
        
        // The AuthEventListener will call Smarticops Facade to log authentication events
        $this->info('Adding subscription of AuthEventListener in app/Providers/EventServiceProvider file...');
        
            file_put_contents(app_path('Providers/EventServiceProvider.php'), str_replace(
                "class EventServiceProvider extends ServiceProvider\n{",
                "class EventServiceProvider extends ServiceProvider\n{".
                "    \n\n".
                "    // automatically generated by $this->signature command from Smarticops package"."\n".
                "    /**\n".
                "    * The subscriber classes to register.\n".
                "    *\n".
                "    * @var array\n".
                "    */\n".
                "    protected \$subscribe = [\n".
                "        'Dvivier\\Smarticops\\Listeners\\AuthEventListener',\n".
                "    ];\n",
                
                file_get_contents(app_path('Providers/EventServiceProvider.php'))
            ));
            
        $this->line('');
        $this->info('Smarticops setup finished.');
    }
}

