<?php

namespace Modular\ConnectorDependencies\Illuminate\Database;

use Modular\ConnectorDependencies\Illuminate\Contracts\Events\Dispatcher;
use Modular\ConnectorDependencies\Illuminate\Contracts\Support\DeferrableProvider;
use Modular\ConnectorDependencies\Illuminate\Database\Console\Migrations\FreshCommand;
use Modular\ConnectorDependencies\Illuminate\Database\Console\Migrations\InstallCommand;
use Modular\ConnectorDependencies\Illuminate\Database\Console\Migrations\MigrateCommand;
use Modular\ConnectorDependencies\Illuminate\Database\Console\Migrations\MigrateMakeCommand;
use Modular\ConnectorDependencies\Illuminate\Database\Console\Migrations\RefreshCommand;
use Modular\ConnectorDependencies\Illuminate\Database\Console\Migrations\ResetCommand;
use Modular\ConnectorDependencies\Illuminate\Database\Console\Migrations\RollbackCommand;
use Modular\ConnectorDependencies\Illuminate\Database\Console\Migrations\StatusCommand;
use Modular\ConnectorDependencies\Illuminate\Database\Migrations\DatabaseMigrationRepository;
use Modular\ConnectorDependencies\Illuminate\Database\Migrations\MigrationCreator;
use Modular\ConnectorDependencies\Illuminate\Database\Migrations\Migrator;
use Modular\ConnectorDependencies\Illuminate\Support\ServiceProvider;
class MigrationServiceProvider extends ServiceProvider implements DeferrableProvider
{
    /**
     * The commands to be registered.
     *
     * @var array
     */
    protected $commands = ['Migrate' => 'command.migrate', 'MigrateFresh' => 'command.migrate.fresh', 'MigrateInstall' => 'command.migrate.install', 'MigrateRefresh' => 'command.migrate.refresh', 'MigrateReset' => 'command.migrate.reset', 'MigrateRollback' => 'command.migrate.rollback', 'MigrateStatus' => 'command.migrate.status', 'MigrateMake' => 'command.migrate.make'];
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->registerRepository();
        $this->registerMigrator();
        $this->registerCreator();
        $this->registerCommands($this->commands);
    }
    /**
     * Register the migration repository service.
     *
     * @return void
     */
    protected function registerRepository()
    {
        $this->app->singleton('migration.repository', function ($app) {
            $table = $app['config']['database.migrations'];
            return new DatabaseMigrationRepository($app['db'], $table);
        });
    }
    /**
     * Register the migrator service.
     *
     * @return void
     */
    protected function registerMigrator()
    {
        // The migrator is responsible for actually running and rollback the migration
        // files in the application. We'll pass in our database connection resolver
        // so the migrator can resolve any of these connections when it needs to.
        $this->app->singleton('migrator', function ($app) {
            $repository = $app['migration.repository'];
            return new Migrator($repository, $app['db'], $app['files'], $app['events']);
        });
    }
    /**
     * Register the migration creator.
     *
     * @return void
     */
    protected function registerCreator()
    {
        $this->app->singleton('migration.creator', function ($app) {
            return new MigrationCreator($app['files'], $app->basePath('stubs'));
        });
    }
    /**
     * Register the given commands.
     *
     * @param  array  $commands
     * @return void
     */
    protected function registerCommands(array $commands)
    {
        foreach (array_keys($commands) as $command) {
            $this->{"register{$command}Command"}();
        }
        $this->commands(array_values($commands));
    }
    /**
     * Register the command.
     *
     * @return void
     */
    protected function registerMigrateCommand()
    {
        $this->app->singleton('command.migrate', function ($app) {
            return new MigrateCommand($app['migrator'], $app[Dispatcher::class]);
        });
    }
    /**
     * Register the command.
     *
     * @return void
     */
    protected function registerMigrateFreshCommand()
    {
        $this->app->singleton('command.migrate.fresh', function () {
            return new FreshCommand();
        });
    }
    /**
     * Register the command.
     *
     * @return void
     */
    protected function registerMigrateInstallCommand()
    {
        $this->app->singleton('command.migrate.install', function ($app) {
            return new InstallCommand($app['migration.repository']);
        });
    }
    /**
     * Register the command.
     *
     * @return void
     */
    protected function registerMigrateMakeCommand()
    {
        $this->app->singleton('command.migrate.make', function ($app) {
            // Once we have the migration creator registered, we will create the command
            // and inject the creator. The creator is responsible for the actual file
            // creation of the migrations, and may be extended by these developers.
            $creator = $app['migration.creator'];
            $composer = $app['composer'];
            return new MigrateMakeCommand($creator, $composer);
        });
    }
    /**
     * Register the command.
     *
     * @return void
     */
    protected function registerMigrateRefreshCommand()
    {
        $this->app->singleton('command.migrate.refresh', function () {
            return new RefreshCommand();
        });
    }
    /**
     * Register the command.
     *
     * @return void
     */
    protected function registerMigrateResetCommand()
    {
        $this->app->singleton('command.migrate.reset', function ($app) {
            return new ResetCommand($app['migrator']);
        });
    }
    /**
     * Register the command.
     *
     * @return void
     */
    protected function registerMigrateRollbackCommand()
    {
        $this->app->singleton('command.migrate.rollback', function ($app) {
            return new RollbackCommand($app['migrator']);
        });
    }
    /**
     * Register the command.
     *
     * @return void
     */
    protected function registerMigrateStatusCommand()
    {
        $this->app->singleton('command.migrate.status', function ($app) {
            return new StatusCommand($app['migrator']);
        });
    }
    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return array_merge(['migrator', 'migration.repository', 'migration.creator'], array_values($this->commands));
    }
}
