BareGit
#include "service.h"
#include "configuration.h"

#include <gtest/gtest.h>

namespace
{

using namespace std::chrono_literals;

TEST(Service, CreatesFreshProtocolProbes)
{
    ServiceConfig config{"blog", "Blog", "Personal blog",
                         HttpEndpoint{"https://example.invalid"}, 5s, 1min,
                         std::nullopt};
    Configuration configuration{2, ":memory:", {{"Personal", {config}}}};
    Service service{configuration.groups.front().services.front()};
    auto first = service.createProbe();
    ASSERT_TRUE(first) << first.error().msg();
    EXPECT_NE(dynamic_cast<HttpProbe*>(first->get()), nullptr);
    auto second = service.createProbe();
    ASSERT_TRUE(second) << second.error().msg();
    EXPECT_NE(first->get(), second->get());
    EXPECT_FALSE(service.in_flight.load());

    service.config.endpoint = TcpEndpoint{"localhost", 80};
    auto tcp = service.createProbe();
    ASSERT_TRUE(tcp) << tcp.error().msg();
    EXPECT_NE(dynamic_cast<TcpProbe*>(tcp->get()), nullptr);

    service.config.endpoint = UdpEndpoint{"localhost", 53, ""};
    auto udp = service.createProbe();
    ASSERT_TRUE(udp) << udp.error().msg();
    EXPECT_NE(dynamic_cast<UdpProbe*>(udp->get()), nullptr);

    service.config.endpoint = IcmpEndpoint{"localhost"};
    auto icmp = service.createProbe();
    ASSERT_TRUE(icmp) << icmp.error().msg();
    EXPECT_NE(dynamic_cast<IcmpProbe*>(icmp->get()), nullptr);
    EXPECT_TRUE(std::holds_alternative<HttpEndpoint>(
        configuration.groups.front().services.front().endpoint));
}

TEST(Service, HttpUrlFallback)
{
    Service service{{"blog", "Blog", "", HttpEndpoint{}, 5s, 1min,
                     "https://example.invalid"}};
    EXPECT_TRUE(service.createProbe());
    EXPECT_TRUE(std::get<HttpEndpoint>(service.config.endpoint).url.empty());

    service.config.url.reset();
    EXPECT_FALSE(service.createProbe());

    service.config.url = "invalid URL";
    EXPECT_FALSE(service.createProbe());

    service.config.endpoint = HttpEndpoint{"https://probe.example.invalid"};
    EXPECT_TRUE(service.createProbe());

    service.config.endpoint = HttpEndpoint{"invalid endpoint URL"};
    service.config.url = "https://example.invalid";
    EXPECT_FALSE(service.createProbe());
}

TEST(Service, UsesServiceTimeoutAndPreservesFlightState)
{
    Service service{{"host", "Host", "", TcpEndpoint{"localhost", 80},
                     0s, 1min, std::nullopt}};
    EXPECT_FALSE(service.createProbe());
    EXPECT_FALSE(service.in_flight.load());

    service.config.timeout = 5s;
    service.in_flight = true;
    EXPECT_TRUE(service.createProbe());
    EXPECT_TRUE(service.in_flight.load());

    service.config.endpoint = TcpEndpoint{"localhost", 0};
    EXPECT_FALSE(service.createProbe());
    EXPECT_TRUE(service.in_flight.load());
}

}