<?php
/**
 * baserCMS :  Based Website Development Project <https://basercms.net>
 * Copyright (c) NPO baser foundation <https://baserfoundation.org/>
 *
 * @copyright     Copyright (c) NPO baser foundation
 * @link          https://basercms.net baserCMS Project
 * @since         5.0.0
 * @license       https://basercms.net/license/index.html MIT License
 */

namespace BaserCore\Test\TestCase\View\Helper;

use BaserCore\Test\Scenario\ContentsScenario;
use BaserCore\Test\Scenario\SitesScenario;
use BaserCore\Test\Scenario\UserGroupsScenario;
use BaserCore\Test\Scenario\UserScenario;
use BaserCore\Test\Scenario\UsersUserGroupsScenario;
use BaserCore\TestSuite\BcTestCase;
use BaserCore\View\BcAdminAppView;
use BaserCore\View\Helper\BcToolbarHelper;
use Cake\Core\Configure;
use Cake\View\View;
use CakephpFixtureFactories\Scenario\ScenarioAwareTrait;

/**
 * Class BcToolbarHelperTest
 */
class BcToolbarHelperTest extends BcTestCase
{
    use ScenarioAwareTrait;

    /**
     * BcToolbarHelper
     * @var BcToolbarHelper
     */
    public $BcToolbar;

    /**
     * setUp
     */
    public function setUp(): void
    {
        parent::setUp();
        $this->loadFixtureScenario(UserScenario::class);
        $this->loadFixtureScenario(UserGroupsScenario::class);
        $this->loadFixtureScenario(UsersUserGroupsScenario::class);
        $this->loadFixtureScenario(ContentsScenario::class);
        $this->loadFixtureScenario(SitesScenario::class);

        $this->BcToolbar = new BcToolbarHelper(new BcAdminAppView($this->getRequest('/')));
    }

    /**
     * tearDown
     */
    public function tearDown(): void
    {
        unset($this->BcToolbar);
        parent::tearDown();
    }

    /**
     * test isAvailableEditLink
     */
    public function testIsAvailableEditLink()
    {
        // editLink 設定なし
        $this->assertFalse($this->BcToolbar->isAvailableEditLink());
        $this->BcToolbar->getView()->set('editLink', 'test');
        // editLink 設定あり
        $this->assertFalse($this->BcToolbar->isAvailableEditLink());
        // ログイン完了
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertTrue($this->BcToolbar->isAvailableEditLink());
        // プレビュー
        $this->BcToolbar->getView()->setRequest($this->getRequest('/?preview=true'));
        $this->assertFalse($this->BcToolbar->isAvailableEditLink());
    }

    /**
     * test isAvailableEditLink
     */
    public function testIsAvailablePublishLink()
    {
        // publishLink 設定なし
        $this->assertFalse($this->BcToolbar->isAvailablePublishLink());
        $this->BcToolbar->getView()->set('publishLink', 'test');
        // publishLink 設定あり
        $this->assertFalse($this->BcToolbar->isAvailablePublishLink());
        // ログイン完了
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertTrue($this->BcToolbar->isAvailablePublishLink());
    }

    /**
     * test isAvailableMode
     */
    public function testisAvailableMode()
    {
        $debug = Configure::read('debug');
        Configure::write('debug', true);
        $this->assertTrue($this->BcToolbar->isAvailableMode());
        Configure::write('debug', false);
        $this->assertFalse($this->BcToolbar->isAvailableMode());
        Configure::write('debug', $debug);
    }

    /**
     * test isAvailableClearCache
     */
    public function testIsAvailableClearCache()
    {
        $this->assertFalse($this->BcToolbar->isAvailableClearCache());
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertTrue($this->BcToolbar->isAvailableClearCache());
    }

    /**
     * test isAvailableBackAgent
     */
    public function testIsAvailableBackAgent()
    {
        $this->assertFalse($this->BcToolbar->isAvailableBackAgent());
        $request = $this->getRequest('/baser/admin');
        $this->loginAdmin($request);
        $session = $request->getSession();
        $session->write('AuthAgent', ['test']);
        $this->assertTrue($this->BcToolbar->isAvailableBackAgent());
    }

    /**
     * test isAvailableLogin
     */
    public function testIsAvailableLogin()
    {
        $this->assertTrue($this->BcToolbar->isAvailableLogin());
        // インストーラーの場合
        $toolbar = new BcToolbarHelper(new View(null, null, null, ['name' => 'Installations']));
        $this->assertFalse($toolbar->isAvailableLogin());
        // ログイン画面の場合
        $toolbar = new BcToolbarHelper(new View($this->getRequest('/baser/admin/baser-core/users/login')));
        $this->assertFalse($toolbar->isAvailableLogin());
        // ログイン済の場合
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertFalse($this->BcToolbar->isAvailableLogin());
    }

    /**
     * test isAvailableAccountSetting
     */
    public function testIsAvailableAccountSetting()
    {
        $this->assertFalse($this->BcToolbar->isAvailableAccountSetting());
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertTrue($this->BcToolbar->isAvailableAccountSetting());
    }

    /**
     * test getAccountSettingUrl
     *
     * @TODO プレフィックスを変更した場合のテスト追加要（mypageなど）
     */
    public function testGetAccountSettingUrl()
    {
        $this->assertEquals('', $this->BcToolbar->getAccountSettingUrl());
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertEquals(['plugin' => 'BaserCore', 'prefix' => 'Admin', 'controller' => 'Users', 'action' => 'edit', 1], $this->BcToolbar->getAccountSettingUrl());
    }

    /**
     * test getLoginUrl
     *
     * @TODO プレフィックスを変更した場合のテスト追加要（mypageなど）
     */
    public function testGetLoginUrl()
    {
        $this->assertEquals('', $this->BcToolbar->getLoginUrl());
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertEquals('/baser/admin/baser-core/users/login', $this->BcToolbar->getLoginUrl());
    }

    /**
     * test getLogoutUrl
     */
    public function testGetLogoutUrl()
    {
        $this->assertEquals('', $this->BcToolbar->getLogoutUrl());
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertEquals([
            'prefix' => 'Admin',
            'plugin' => 'BaserCore',
            'controller' => 'Users',
            'action' => 'logout'
        ], $this->BcToolbar->getLogoutUrl());
    }

    /**
     * test getMode
     */
    public function testGetMode()
    {
        $debug = Configure::read('debug');
        // デバッグ
        Configure::write('debug', true);
        $this->assertEquals('debug', $this->BcToolbar->getMode());
        // インストール
        Configure::write('debug', false);
        $_SERVER['INSTALL_MODE'] = "true";
        $this->assertEquals('install', $this->BcToolbar->getMode());
        // なし
        $_SERVER['INSTALL_MODE'] = "false";
        $this->assertEquals('', $this->BcToolbar->getMode());
        Configure::write('debug', $debug);
    }

    /**
     * test getModeTitle
     */
    public function testGetModeTitle()
    {
        $debug = Configure::read('debug');
        // デバッグ
        Configure::write('debug', true);
        $this->assertEquals('デバッグモード', $this->BcToolbar->getModeTitle());
        // インストール
        Configure::write('debug', false);
        $_SERVER['INSTALL_MODE'] = "true";
        $this->assertEquals('インストールモード', $this->BcToolbar->getModeTitle());
        // なし
        $_SERVER['INSTALL_MODE'] = "false";
        $this->assertEquals('', $this->BcToolbar->getModeTitle());
        Configure::write('debug', $debug);
    }

    /**
     * test getModeDescription
     */
    public function testGetModeDescription()
    {
        $debug = Configure::read('debug');
        // デバッグ
        Configure::write('debug', true);
        $this->assertMatchesRegularExpression('/デバッグモードです。/', $this->BcToolbar->getModeDescription());
        // インストール
        Configure::write('debug', false);
        $_SERVER['INSTALL_MODE'] = "true";
        $this->assertMatchesRegularExpression('/インストールモードです。/', $this->BcToolbar->getModeDescription());
        // なし
        $_SERVER['INSTALL_MODE'] = "false";
        $this->assertEquals('', $this->BcToolbar->getModeDescription());
        Configure::write('debug', $debug);
    }

    /**
     * test isLoginUrl
     */
    public function testIsLoginUrl()
    {
        $this->assertFalse($this->BcToolbar->isLoginUrl());
        $bcToolbar = new BcToolbarHelper(new View($this->getRequest('/baser/admin/baser-core/users/login')));
        $this->assertTrue($bcToolbar->isLoginUrl());
    }

    /**
     * test getLogoType
     */
    public function testGetLogoType()
    {
        // フロントで管理画面利用不可
        $this->assertEquals('frontAdminNotAvailable', $this->BcToolbar->getLogoType());
        // フロントで管理画面利用可能
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertEquals('frontAdminAvailable', $this->BcToolbar->getLogoType());
        // ノーマル
        $bcToolbar = new BcToolbarHelper(new View($this->getRequest('/baser/admin/baser-core/users/login')));
        $this->assertEquals('normal', $bcToolbar->getLogoType());
        // アップデーター
        $bcToolbar->getView()->setRequest($this->getRequest('/baser/admin/baser-core/plugins/update'));
        $this->assertEquals('update', $bcToolbar->getLogoType());
        // インストーラー
        $bcToolbar = new BcToolbarHelper(new View(null, null, null, ['name' => 'Installations']));
        $this->assertEquals('install', $bcToolbar->getLogoType());
    }

    /**
     * test getLogoLink
     */
    public function testGetLogoLink()
    {
        // フロントで管理画面利用不可
        $this->assertEquals('', $this->BcToolbar->getLogoLink());
        // フロントで管理画面利用可能
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertEquals(['prefix' => 'Admin', 'plugin' => 'BaserCore', 'controller' => 'dashboard', 'action' => 'index'], $this->BcToolbar->getLogoLink());
        // ノーマル
        $bcToolbar = new BcToolbarHelper(new View($this->getRequest('/baser/admin/baser-core/users/login')));
        $this->assertEquals('https://localhost/', $bcToolbar->getLogoLink());
        // アップデーター
        $bcToolbar->getView()->setRequest($this->getRequest('/baser/admin/baser-core/plugins/update'));
        $this->assertEquals('https://baserproject.github.io/5/operation/update', $bcToolbar->getLogoLink());
        // インストーラー
        Configure::write('BcEnv.isInstalled', false);
        $bcToolbar = new BcToolbarHelper(new View(null, null, null, ['name' => 'Installations']));
        $this->assertEquals('https://baserproject.github.io/5/introduce/', $bcToolbar->getLogoLink());
        Configure::write('BcEnv.isInstalled', true);
    }

    /**
     * test getLogoText
     */
    public function testGetLogoText()
    {
        // フロントで管理画面利用不可
        $this->assertEquals('メインサイト', $this->BcToolbar->getLogoText());
        // フロントで管理画面利用可能
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $this->assertEquals('ダッシュボード', $this->BcToolbar->getLogoText());
        // ノーマル
        $bcToolbar = new BcToolbarHelper(new View($this->getRequest('/baser/admin/baser-core/users/login')));
        $this->assertEquals('サイト表示', $bcToolbar->getLogoText());
        // アップデーター
        $bcToolbar->getView()->setRequest($this->getRequest('/baser/admin/baser-core/plugins/update'));
        $this->assertEquals('アップデートマニュアル', $bcToolbar->getLogoText());
        // インストーラー
        $bcToolbar = new BcToolbarHelper(new View(null, null, null, ['name' => 'Installations']));
        $this->assertEquals('インストールマニュアル', $bcToolbar->getLogoText());
    }

    /**
     * test getLogoLinkOptions
     */
    public function testGetLogoLinkOptions()
    {
        // フロントで管理画面利用不可
        $this->assertEquals([
            'title' => 'メインサイト',
            'class' => 'bca-toolbar__logo-link',
            'escapeTitle' => false
        ], $this->BcToolbar->getLogoLinkOptions());

        // フロントで管理画面利用可能
        $this->loginAdmin($this->getRequest('/baser/admin'));
        $options = $this->BcToolbar->getLogoLinkOptions();
        $this->assertTrue(in_array('bca-toolbar__logo-link', $options));

        // ノーマル
        $bcToolbar = new BcToolbarHelper(new View($this->getRequest('/baser/admin/baser-core/users/login')));
        $options = $bcToolbar->getLogoLinkOptions();
        $this->assertTrue(in_array('bca-toolbar__logo-link', $options));

        // アップデーター
        $bcToolbar->getView()->setRequest($this->getRequest('/baser/admin/baser-core/plugins/update'));
        $options = $bcToolbar->getLogoLinkOptions();
        $this->assertTrue(in_array('bca-toolbar__logo-link', $options));
        $this->assertTrue(in_array('_blank', $options));

        // インストーラー
        $bcToolbar = new BcToolbarHelper(new View(null, null, null, ['name' => 'Installations']));
        $options = $bcToolbar->getLogoLinkOptions();
        $this->assertTrue(in_array('bca-toolbar__logo-link', $options));
        $this->assertTrue(in_array('_blank', $options));
    }

}
