<?php

namespace Pixinvent\Jetstrap\Tests;

use Illuminate\Filesystem\Filesystem;
use Illuminate\Foundation\Application;
use Pixinvent\Jetstrap\JetstrapServiceProvider;

class TestCase extends \Orchestra\Testbench\TestCase
{
  protected $filesystem;

  /**
   * Setup the test environment.
   *
   * @return void
   */
  protected function setUp(): void
  {
    parent::setUp();
    // additional setup

    $this->filesystem = new Filesystem();
  }

  /**
   * Clean up the testing environment before the next test.
   *
   * @return void
   */
  protected function tearDown(): void
  {
    parent::tearDown();
    $this->cleanResourceDirectory($this->filesystem);
    $this->cleanLivewireFiles($this->filesystem);
    $this->cleanInertiaFiles($this->filesystem);
  }

  /**
   * Get package providers.
   *
   * @param  Application  $app
   *
   * @return array
   */
  protected function getPackageProviders($app)
  {
    return [
      JetstrapServiceProvider::class,
    ];
  }

  /**
   * Define environment setup.
   *
   * @param  Application   $app
   *
   * @return void
   */
  protected function getEnvironmentSetUp($app)
  {
    // perform environment setup
  }

  /**
   * Remove files generated by Jetstrap
   *
   * @param Filesystem $filesystem
   * @return void
   */
  protected function cleanResourceDirectory(Filesystem $filesystem)
  {
    if ($filesystem->exists(base_path('webpack.mix.js'))) {
      unlink(base_path('webpack.mix.js'));
    }
    if ($filesystem->isDirectory(resource_path('views/auth'))) {
      $filesystem->deleteDirectory(resource_path('views/auth'));
    }
    if ($filesystem->isDirectory(resource_path('views/layouts'))) {
      $filesystem->deleteDirectory(resource_path('views/layouts'));
    }
    if ($filesystem->isDirectory(resource_path('views/components'))) {
      $filesystem->deleteDirectory(resource_path('views/components'));
    }
    if ($filesystem->isDirectory(base_path('public/css'))) {
      $filesystem->deleteDirectory(base_path('public/css'));
    }
    if ($filesystem->isDirectory(resource_path('sass'))) {
      $filesystem->deleteDirectory(resource_path('sass'));
    }
  }

  /**
   * Remove files and directory generated for livewire stack
   *
   * @param Filesystem $filesystem
   * @return void
   */
  protected function cleanLivewireFiles(Filesystem $filesystem)
  {
    // make sure we're starting from a clean state
    if ($filesystem->exists(resource_path('views/app.blade.php'))) {
      $filesystem->delete(resource_path('views/app.blade.php'));
    }
    if ($filesystem->exists(resource_path('views/dashboard.blade.php'))) {
      $filesystem->delete(resource_path('views/dashboard.blade.php'));
    }
    if ($filesystem->exists(resource_path('views/welcome.blade.php'))) {
      $filesystem->delete(resource_path('views/welcome.blade.php'));
    }
    if ($filesystem->isDirectory(resource_path('views/api'))) {
      $filesystem->deleteDirectory(resource_path('views/api'));
    }
    if ($filesystem->isDirectory(resource_path('views/profile'))) {
      $filesystem->deleteDirectory(resource_path('views/profile'));
    }
    if ($filesystem->isDirectory(resource_path('views/vendor'))) {
      $filesystem->deleteDirectory(resource_path('views/vendor'));
    }
    if ($filesystem->isDirectory(resource_path('views/teams'))) {
      $filesystem->deleteDirectory(resource_path('views/teams'));
    }
  }

  /**
   * Remove files and directory generated for inertia stack
   *
   * @param Filesystem $filesystem
   * @return void
   */
  protected function cleanInertiaFiles(Filesystem $filesystem)
  {
    // make sure we're starting from a clean state
    if ($filesystem->isDirectory(resource_path('js'))) {
      $filesystem->cleanDirectory(resource_path('js'));
    }
  }

  /**
   * Basic tests shared across all methods
   *
   * @return void
   */
  protected function basicTests()
  {
    $this->assertFalse($this->filesystem->exists(base_path('tailwind.config.js')));
    $this->assertFalse($this->filesystem->exists(resource_path('css')));
    $this->assertTrue($this->filesystem->exists(base_path('webpack.mix.js')));
  }

  /**
   * Basic tests shared across all livewire test methods
   *
   * @return void
   */
  protected function basicLivewireTests()
  {
    $this->assertTrue($this->filesystem->exists(resource_path('views/layouts/app.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/layouts/guest.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/dashboard.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/terms.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/policy.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/navigation-menu.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/api/api-token-manager.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/api/index.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/profile/delete-user-form.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/profile/logout-other-browser-sessions-form.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/profile/show.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/profile/two-factor-authentication-form.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/profile/update-password-form.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/profile/update-profile-information-form.blade.php')));

    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/action-message.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/action-section.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/application-logo.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/application-mark.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/authentication-card.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/authentication-card-logo.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/button.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/banner.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/confirmation-modal.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/checkbox.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/danger-button.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/dialog-modal.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/dropdown.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/dropdown-link.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/form-section.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/input.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/input-error.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/label.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/modal.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/nav-link.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/secondary-button.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/section-border.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/section-title.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/switchable-team.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/validation-errors.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/vendor/jetstream/components/welcome.blade.php')));
  }

  /**
   * Basic tests shared across all inertia test methods
   *
   * @return void
   */
  protected function basicInertiaTests()
  {
    $this->assertTrue($this->filesystem->exists(resource_path('views/app.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/ActionMessage.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/ActionSection.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/ApplicationLogo.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/ApplicationMark.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/Banner.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/Button.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/ConfirmationModal.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/Checkbox.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/DangerButton.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/DialogModal.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/Dropdown.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/DropdownLink.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/FormSection.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/Input.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/InputError.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/Label.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/Modal.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/NavLink.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/SecondaryButton.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/SectionBorder.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/SectionTitle.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Jetstream/Welcome.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Layouts/AppLayout.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Dashboard.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/API/ApiTokenManager.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/API/Index.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Profile/DeleteUserForm.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Profile/LogoutOtherBrowserSessionsForm.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Profile/Show.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Profile/TwoFactorAuthenticationForm.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Profile/UpdatePasswordForm.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Profile/UpdateProfileInformationForm.vue')));
  }

  /**
   * Test for inertia team assets
   *
   * @return void
   */
  protected function inertiaTeamTests()
  {
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Teams/Create.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Teams/CreateTeamForm.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Teams/DeleteTeamForm.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Teams/Show.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Teams/TeamMemberManager.vue')));
    $this->assertTrue($this->filesystem->exists(resource_path('js/Pages/Teams/UpdateTeamNameForm.vue')));
  }

  /**
   * Test for livewire team assets
   *
   * @return void
   */
  protected function livewireTeamTests()
  {
    $this->assertTrue($this->filesystem->exists(resource_path('views/teams/create.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/teams/create-team-form.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/teams/delete-team-form.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/teams/show.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/teams/team-member-manager.blade.php')));
    $this->assertTrue($this->filesystem->exists(resource_path('views/teams/update-team-name-form.blade.php')));
  }
}
