<?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
 *
 */

declare(strict_types=1);

namespace Tests\Core\AgentConfiguration\Application\UseCase\FindAgentConfiguration;

use Core\AgentConfiguration\Application\Exception\AgentConfigurationException;
use Core\AgentConfiguration\Application\Repository\ReadAgentConfigurationRepositoryInterface;
use Core\AgentConfiguration\Application\UseCase\FindAgentConfiguration\FindAgentConfiguration;
use Core\AgentConfiguration\Application\UseCase\FindAgentConfiguration\FindAgentConfigurationResponse;
use Core\AgentConfiguration\Domain\Model\AgentConfiguration;
use Core\AgentConfiguration\Domain\Model\ConfigurationParameters\TelegrafConfigurationParameters;
use Core\AgentConfiguration\Domain\Model\ConnectionModeEnum;
use Core\AgentConfiguration\Domain\Model\Poller;
use Core\AgentConfiguration\Domain\Model\Type;
use Core\Application\Common\UseCase\ErrorResponse;
use Core\Application\Common\UseCase\NotFoundResponse;
use Core\Host\Application\Repository\ReadHostRepositoryInterface;

beforeEach(function (): void {
    $this->useCase = new FindAgentConfiguration(
        readRepository: $this->readRepository = $this->createMock(ReadAgentConfigurationRepositoryInterface::class),
        readHostRepository: $this->readHostRepository = $this->createMock(ReadHostRepositoryInterface::class),
    );
});

it('should present a Not Found Response when object does not exist', function (): void {
    $this->readRepository
        ->expects($this->once())
        ->method('find')
        ->willReturn(null);

    $response = ($this->useCase)(1);

    expect($response)
        ->toBeInstanceOf(NotFoundResponse::class)
        ->and($response->getMessage())
        ->toBe('Agent Configuration not found');
});

it('should present an Error Response when an unexpected error occurs', function (): void {
    $this->readRepository
        ->expects($this->once())
        ->method('find')
        ->willThrowException(new \Exception());

    $response = ($this->useCase)(1);

    expect($response)
        ->toBeInstanceOf(ErrorResponse::class)
        ->and($response->getMessage())
        ->toBe(AgentConfigurationException::errorWhileRetrievingObject()->getMessage());
});

it('should present a FindConfigurationResponse when everything is ok', function (): void {
    $configuration = new TelegrafConfigurationParameters(
        [
            'otel_server_address' => '10.10.10.10',
            'otel_server_port' => 453,
            'otel_public_certificate' => 'public_certif.crt',
            'otel_ca_certificate' => 'ca_certif.cer',
            'otel_private_key' => 'otel-key.key',
            'conf_server_port' => 454,
            'conf_certificate' => 'conf-certif.crt',
            'conf_private_key' => 'conf-key.key',
        ]
    );

    $pollers = [
        new Poller(1, 'pollerOne'),
        new Poller(2, 'pollerTwo'),
    ];

    $this->readRepository
        ->expects($this->once())
        ->method('find')
        ->willReturn(
            new AgentConfiguration(
                id: 1,
                name: 'acOne',
                type: Type::TELEGRAF,
                connectionMode: ConnectionModeEnum::SECURE,
                configuration: $configuration
            )
        );

    $this->readRepository
        ->expects($this->once())
        ->method('findPollersByAcId')
        ->willReturn($pollers);

    $response = ($this->useCase)(1);

    expect($response)
        ->toBeInstanceOf(FindAgentConfigurationResponse::class)
        ->and($response->agentConfiguration->getId())->toBe(1)
        ->and($response->agentConfiguration->getName())->toBe('acOne')
        ->and($response->agentConfiguration->getType())->toBe(Type::TELEGRAF)
        ->and($response->agentConfiguration->getConnectionMode())->toBe(ConnectionModeEnum::SECURE)
        ->and($response->agentConfiguration->getConfiguration()->getData())->toBe([
            'otel_server_address' => '10.10.10.10',
            'otel_server_port' => 453,
            'otel_public_certificate' => '/etc/pki/public_certif.crt',
            'otel_ca_certificate' => '/etc/pki/ca_certif.cer',
            'otel_private_key' => '/etc/pki/otel-key.key',
            'conf_server_port' => 454,
            'conf_certificate' => '/etc/pki/conf-certif.crt',
            'conf_private_key' => '/etc/pki/conf-key.key',
        ])
        ->and($response->pollers[0]->getId())->toBe(1)
        ->and($response->pollers[0]->getName())->toBe('pollerOne')
        ->and($response->pollers[1]->getId())->toBe(2)
        ->and($response->pollers[1]->getName())->toBe('pollerTwo');
});
