<?php

/*
 * Copyright 2005 - 2025 Centreon (https://www.centreon.com/)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * For more information : contact@centreon.com
 *
 */

namespace CentreonLegacy\Core\Widget;

use Centreon\Test\Mock\CentreonDB;
use Centreon\Test\Mock\DependencyInjector\ConfigurationDBProvider;
use Centreon\Test\Mock\DependencyInjector\FilesystemProvider;
use Centreon\Test\Mock\DependencyInjector\FinderProvider;
use Centreon\Test\Mock\DependencyInjector\ServiceContainer;
use Pimple\Psr11\Container;

class InformationTest extends \PHPUnit\Framework\TestCase
{
    private $container;

    private $db;

    private $utils;

    private $configuration;

    public function setUp(): void
    {
        $this->container = new ServiceContainer();

        $this->db = new CentreonDB();

        $this->utils = $this->getMockBuilder(\CentreonLegacy\Core\Utils\Utils::class)
            ->disableOriginalConstructor()
            ->getMock();

        $this->configuration = ['title' => 'My Widget', 'author' => 'Centreon', 'email' => 'contact@centreon.com', 'website' => 'http://www.centreon.com', 'description' => 'Widget for displaying host monitoring information', 'version' => '1.0.0', 'keywords' => 'centreon, widget, host, monitoring', 'screenshot' => '', 'thumbnail' => './widgets/host-monitoring/resources/centreon-logo.png', 'url' => './widgets/host-monitoring/index.php', 'directory' => 'my-widget', 'preferences' => ['preference' => [['@attributes' => ['label' => 'Host Name', 'name' => 'host_name_search', 'defaultValue' => '', 'type' => 'compare', 'header' => 'Filters']]]]];
    }

    public function tearDown(): void
    {
        $this->container->terminate();
        $this->container = null;
    }

    public function testGetConfiguration(): void
    {
        $expectedResult = $this->configuration;
        $expectedResult['autoRefresh'] = 0;

        $filesystem = $this->getMockBuilder(\Symfony\Component\Filesystem\Filesystem::class)
            ->disableOriginalConstructor()
            ->onlyMethods(['exists'])
            ->getMock();
        $filesystem->expects($this->any())
            ->method('exists')
            ->willReturn(true);
        $this->container->registerProvider(new FilesystemProvider($filesystem));

        $this->utils->expects($this->any())
            ->method('buildPath')
            ->willReturn('MyWidget');
        $this->utils->expects($this->any())
            ->method('xmlIntoArray')
            ->willReturn($this->configuration);

        $information = new Information(new Container($this->container), $this->utils);
        $configuration = $information->getConfiguration('my-widget');

        $this->assertEquals($configuration, $expectedResult);
    }

    public function testGetTypes(): void
    {
        $expectedResult = ['type1' => ['id' => 1, 'name' => 'type1']];

        $query = 'SELECT ft_typename, field_type_id '
            . 'FROM widget_parameters_field_type ';
        $this->db->addResultSet(
            $query,
            [['ft_typename' => 'type1', 'field_type_id' => 1]]
        );

        $this->container->registerProvider(new ConfigurationDBProvider($this->db));

        $information = new Information(new Container($this->container), $this->utils);
        $types = $information->getTypes();

        $this->assertEquals($types, $expectedResult);
    }

    public function testGetParameterIdByName(): void
    {
        $query = 'SELECT parameter_id '
            . 'FROM widget_parameters '
            . 'WHERE parameter_code_name = :name ';
        $this->db->addResultSet(
            $query,
            [['parameter_id' => 1]]
        );

        $this->container->registerProvider(new ConfigurationDBProvider($this->db));

        $information = new Information(new Container($this->container), $this->utils);
        $id = $information->getParameterIdByName('MyWidget');

        $this->assertEquals($id, 1);
    }

    public function testGetParameters(): void
    {
        $expectedResult = ['parameter1' => ['parameter_id' => 1, 'parameter_name' => 'parameter 1', 'parameter_code_name' => 'parameter1', 'default_value' => '', 'parameter_order' => 1, 'header_title' => 'title', 'require_permission' => null, 'widget_model_id' => 1, 'field_type_id' => 1]];

        $query = 'SELECT * '
            . 'FROM widget_parameters '
            . 'WHERE widget_model_id = :id ';
        $this->db->addResultSet(
            $query,
            [['parameter_id' => 1, 'parameter_name' => 'parameter 1', 'parameter_code_name' => 'parameter1', 'default_value' => '', 'parameter_order' => 1, 'header_title' => 'title', 'require_permission' => null, 'widget_model_id' => 1, 'field_type_id' => 1]]
        );

        $this->container->registerProvider(new ConfigurationDBProvider($this->db));

        $information = new Information(new Container($this->container), $this->utils);
        $parameters = $information->getParameters(1);

        $this->assertEquals($parameters, $expectedResult);
    }

    public function testGetIdByName(): void
    {
        $query = 'SELECT widget_model_id '
            . 'FROM widget_models '
            . 'WHERE directory = :directory';
        $this->db->addResultSet(
            $query,
            [['widget_model_id' => 1]]
        );

        $this->container->registerProvider(new ConfigurationDBProvider($this->db));

        $information = new Information(new Container($this->container), $this->utils);
        $id = $information->getIdByName('MyWidget');

        $this->assertEquals($id, 1);
    }

    public function testGetAvailableList(): void
    {
        $configuration = $this->configuration;
        $configuration['autoRefresh'] = 0;
        $expectedResult = ['my-widget' => $configuration];

        $finder = $this->getMockBuilder(\Symfony\Component\Finder\Finder::class)
            ->disableOriginalConstructor()
            ->onlyMethods(['directories', 'depth', 'in', 'getIterator'])
            ->getMock();
        $finder->expects($this->any())
            ->method('directories')
            ->willReturn($finder);
        $finder->expects($this->any())
            ->method('depth')
            ->willReturn($finder);
        $finder->expects($this->any())
            ->method('in')
            ->willReturn($finder);
        $finder->expects($this->any())
            ->method('getIterator')
            ->willReturn(new \ArrayIterator([new \SplFileInfo('my-widget')]));
        $this->container->registerProvider(new FinderProvider($finder));

        $filesystem = $this->getMockBuilder(\Symfony\Component\Filesystem\Filesystem::class)
            ->disableOriginalConstructor()
            ->onlyMethods(['exists'])
            ->getMock();
        $filesystem->expects($this->any())
            ->method('exists')
            ->willReturn(true);
        $this->container->registerProvider(new FilesystemProvider($filesystem));

        $this->utils->expects($this->any())
            ->method('buildPath')
            ->willReturn('MyWidget');
        $this->utils->expects($this->any())
            ->method('xmlIntoArray')
            ->willReturn($this->configuration);

        $information = new Information(new Container($this->container), $this->utils);
        $list = $information->getAvailableList();

        $this->assertEquals($list, $expectedResult);
    }

    public function testGetList(): void
    {
        $configuration = $this->configuration;
        $configuration['autoRefresh'] = 0;
        $configuration['source_available'] = true;
        $configuration['is_installed'] = true;
        $configuration['upgradeable'] = false;
        $configuration['installed_version'] = '1.0.0';
        $configuration['available_version'] = '1.0.0';
        $configuration['id'] = 1;
        unset($configuration['version']);

        $expectedResult = ['my-widget' => $configuration];

        $this->db->addResultSet(
            'SELECT * FROM widget_models ',
            [['widget_model_id' => 1, 'title' => 'my title', 'description' => 'my description', 'url' => '', 'version' => '1.0.0', 'is_internal' => 0, 'directory' => 'my-widget', 'author' => 'phpunit', 'email' => 'root@localhost', 'website' => 'centreon.com', 'keywords' => 'centreon', 'screenshot' => null, 'thumbnail' => '', 'autoRefresh' => 0]]
        );
        $this->container->registerProvider(new ConfigurationDBProvider($this->db));

        $this->utils->expects($this->any())
            ->method('buildPath')
            ->willReturn('MyWidget');

        $finder = $this->getMockBuilder(\Symfony\Component\Finder\Finder::class)
            ->disableOriginalConstructor()
            ->onlyMethods(['directories', 'depth', 'in', 'getIterator'])
            ->getMock();
        $finder->expects($this->any())
            ->method('directories')
            ->willReturn($finder);
        $finder->expects($this->any())
            ->method('depth')
            ->willReturn($finder);
        $finder->expects($this->any())
            ->method('in')
            ->willReturn($finder);
        $finder->expects($this->any())
            ->method('getIterator')
            ->willReturn(new \ArrayIterator([new \SplFileInfo('my-widget')]));
        $this->container->registerProvider(new FinderProvider($finder));

        $filesystem = $this->getMockBuilder(\Symfony\Component\Filesystem\Filesystem::class)
            ->disableOriginalConstructor()
            ->onlyMethods(['exists'])
            ->getMock();
        $filesystem->expects($this->any())
            ->method('exists')
            ->willReturn(true);
        $this->container->registerProvider(new FilesystemProvider($filesystem));

        $this->utils->expects($this->any())
            ->method('xmlIntoArray')
            ->willReturn($this->configuration);

        $information = new Information(new Container($this->container), $this->utils);
        $list = $information->getList();

        $this->assertEquals($list, $expectedResult);
    }
}
