<?php
declare(strict_types=1);

/**
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 *
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 *
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
 * @link          https://cakephp.org CakePHP(tm) Project
 * @since         2.1.0
 * @license       https://www.opensource.org/licenses/mit-license.php MIT License
 */
namespace DebugKit\Test\TestCase\Panel;

use Cake\Core\Configure;
use Cake\Datasource\ConnectionManager;
use Cake\TestSuite\TestCase;
use DebugKit\Panel\SqlLogPanel;
use ReflectionProperty;

/**
 * Class SqlLogPanelTest
 */
class SqlLogPanelTest extends TestCase
{
    /**
     * @var SqlLogPanel
     */
    protected $panel;

    /**
     * @var
     */
    protected $logger;

    /**
     * Setup
     *
     * @return void
     */
    public function setUp(): void
    {
        parent::setUp();
        $this->panel = new SqlLogPanel();
        $this->logger = ConnectionManager::get('test')->getDriver()->getLogger();
    }

    public function tearDown(): void
    {
        parent::tearDown();

        if ($this->logger) {
            ConnectionManager::get('test')->getDriver()->setLogger($this->logger);
        }
    }

    /**
     * Ensure that subrequests don't double proxy the logger.
     *
     * @return void
     */
    public function testInitializeTwiceNoDoubleProxy()
    {
        $this->panel->initialize();
        $db = ConnectionManager::get('test');
        $logger = $db->getDriver()->getLogger();
        $this->assertInstanceOf('DebugKit\Database\Log\DebugLog', $logger);

        $this->panel->initialize();
        $second = $db->getDriver()->getLogger();
        $this->assertSame($second, $logger);
    }

    /**
     * Ensure that subrequests don't double proxy the logger.
     *
     * @return void
     */
    public function testInitializePassesIncludeSchema()
    {
        Configure::write('DebugKit.includeSchemaReflection', true);
        $this->panel->initialize();
        $db = ConnectionManager::get('test');
        $logger = $db->getDriver()->getLogger();
        $this->assertInstanceOf('DebugKit\Database\Log\DebugLog', $logger);

        $property = new ReflectionProperty($logger, '_includeSchema');
        $property->setAccessible(true);
        $this->assertTrue($property->getValue($logger));
    }

    /**
     * test the parsing of source list.
     *
     * @return void
     */
    public function testData()
    {
        $this->panel->initialize();

        /** @var Table $articles */
        $articles = $this->getTableLocator()->get('Articles');
        $articles->findById(1)->first();

        $result = $this->panel->data();
        $this->assertArrayHasKey('loggers', $result);
    }

    /**
     * Test getting summary data.
     *
     * @return void
     */
    public function testSummary()
    {
        $this->panel->initialize();

        /** @var Table $articles */
        $articles = $this->getTableLocator()->get('Articles');
        $articles->findById(1)->first();

        $result = $this->panel->summary();
        $this->assertMatchesRegularExpression('/\d+ \\/ \d+(\.\d+)? ms/', $result);
    }

    /**
     * Testing a simple connection (no set/getLogger on driver).
     *
     * @return void
     */
    public function testWithSimpleConnection()
    {
        ConnectionManager::setConfig('simple', [
            'className' => 'DebugKit\TestApp\Stub\SimpleConnectionStub',
        ]);

        $this->panel->addConnection('simple'); // should not throw an error
        $this->assertTrue(true);

        ConnectionManager::drop('simple');
    }
}
