<?php

namespace Ignite\Core\Tests;

use Ignite\Core\Entities\Group;
use Ignite\Core\Entities\User;
use Illuminate\Console\Application as Artisan;
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
use Orchestra\Testbench\TestCase as BaseTestCase;

class TestCase extends BaseTestCase
{
    protected function setUp(): void
    {
        parent::setUp();
    }

    /**
     * Login as admin is more for readability.
     *
     * @param int $id
     * @return User
     */
    protected function loginAsAdmin($id = 1)
    {
        /** @var User $user */
        try {
            $user = User::with(['groups'])->where('user_id', $id)->firstOrFail();
        } catch (\Exception $e) {
            $user = factory(User::class)->create();
            $group = factory(Group::class)->create();
            $user->groups()->save($group);
            $user->fresh()->load('groups');
        }

        if (! $user) {
            $this->assertInstanceOf(User::class, $user, 'Unable to find test user.');
        }

        $this->app['authorization']->forgetPermissions()->registerPermissions();

        $this->actingAs($user);

        return $user;
    }

    /**
     * Load the routes for a module or many modules.
     *
     * @param string|array $modules
     */
    protected function loadRoutes($modules)
    {
        if (is_string($modules)) {
            $modules = [$modules];
        }

        /** @var Router $router */
        $router = app(Router::class);
        $routes = $router->getRoutes();

        foreach ($modules as $key => $module) {
            Route::group([
                'prefix' => '/admin',
                'namespace' => '\Ignite\Core\Http\Controllers',
                'middleware' => ['web'],
            ], function () use ($modules, $key) {
                $modules[$key] = realpath(__DIR__."/../routes/web.php");
                require $modules[$key];
            });
        }

        app()->instance('routes', $routes);

        app()->rebinding('routes', function ($app, $routes) {
            $app['url']->setRoutes($routes);
        });

        app(Router::class)->getRoutes()->refreshNameLookups();
    }

    /**
     * Load and resolve commands.
     *
     * @param $commands
     */
    protected function loadCommands($commands)
    {
        $commands = is_array($commands) ? $commands : func_get_args();

        Artisan::starting(function ($artisan) use ($commands) {
            $artisan->resolveCommands($commands);
        });
    }

    /**
     * Get the aliases for the Ignite package.
     *
     * @param \Illuminate\Foundation\Application $app
     * @return array
     */
    protected function getPackageAliases($app)
    {
        return [
            'Validator' => \Illuminate\Support\Facades\Validator::class,
            'Form' => \Collective\Html\FormFacade::class,
            'Html' => \Collective\Html\HtmlFacade::class,
            'Flash' => \Ignite\Flash\Facades\Flash::class,
        ];
    }

    /**
     * Reset the database.
     */
    protected function resetDatabase()
    {
        $this->artisan('migrate:reset', [
            '--database' => 'testing',
        ]);
    }

    /**
     * Seed the database for one or many modules.
     *
     * @param null|string|array $seeds
     */
    protected function seedModules($seeds)
    {
        if (! is_null($seeds) && is_string($seeds)) {
            $seeds = [$seeds];
        }

        $seeders = [
            'core' => '\Ignite\Core\Database\Seeders\CoreDatabaseSeeder',
        ];

        foreach ($seeders as $module => $seeder) {
            if (in_array($module, $seeds)) {
                $this->artisan('db:seed', [
                    '--class' => $seeder,
                    '--database' => 'testing',
                ]);
            }
        }
    }

    /**
     * Get the providers registered with the Ignite package.
     *
     * @param \Illuminate\Foundation\Application $app
     * @return array
     */
    protected function getPackageProviders($app)
    {
        return [
            \Nwidart\Modules\LaravelModulesServiceProvider::class,
            //\Nwidart\Modules\Providers\BootstrapServiceProvider::class,
            \Ignite\Core\Providers\ViewServiceProvider::class,
            \Ignite\Core\Providers\CoreServiceProvider::class,
            \Collective\Html\HtmlServiceProvider::class,
            \Ignite\Flash\FlashServiceProvider::class,
            \Kris\LaravelFormBuilder\FormBuilderServiceProvider::class,
            \Maatwebsite\Excel\ExcelServiceProvider::class,
        ];
    }

    /**
     * Define environment setup.
     *
     * @param \Illuminate\Foundation\Application $app
     * @return void
     */
    protected function getEnvironmentSetUp($app)
    {
        $app['config']->set('app.env', 'testing');
        $app['config']->set('database.default', 'testing');
        $app['config']->set('database.connections.testing', [
            'driver' => 'mysql',
            'host' => getenv('MYSQL_HOST') ?: '127.0.0.1',
            'port' => '3306',
            'database' => getenv('MYSQL_DATABASE') ?: 'threedotzero_test',
            'username' => getenv('MYSQL_USERNAME') ?: 'homestead',
            'password' => getenv('MYSQL_PASSWORD') ?: 'secret',
        ]);
        $app['config']->set('core.admin', [
            'email' => getenv('ADMIN_EMAIL') ?: 'it@brightspot.email',
            'password' => getenv('ADMIN_PASSWORD') ?: 'br1ght3r1d34s!',
        ]);
    }
}
