// Copyright 2021 Google LLC
//
// 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
//
//      http://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.

#include "socket_manager.hpp"

#include "serializer.hpp"

#include <errno.h>
#include <fmt/format.h>
#include <sys/socket.h>
#include <unistd.h>

#include <phosphor-logging/log.hpp>

#include <cstring>

using fmt::format;
using phosphor::logging::level;
using phosphor::logging::log;

SocketManager::~SocketManager()
{
    std::lock_guard<std::mutex> lock(open_sockets_lock_);
    for (auto fd : open_sockets_)
    {
        close(fd);
    }
}

void SocketManager::SendDatagram(const NemoraDatagram* bcast)
{
    std::string serialized = Serializer::Serialize(bcast);

    // Create socket
    auto fd = socket(AF_INET6, SOCK_DGRAM, 0);
    if (fd < 0)
    {
        log<level::ERR>("SocketManager::SendDatagram: Couldn't open socket");
    }
    TrackSocket(fd);

    // Because we aren't sure whether the v6 or v4 target IP will be present,
    // we send UDP packets to both. This puts us at feature parity with EC.

    // Send serialized data (v6)
    auto addr6 = reinterpret_cast<const sockaddr*>(&bcast->destination6);
    auto err = sendto(fd, serialized.c_str(), serialized.length(), 0, addr6,
                      sizeof(bcast->destination6));
    if (err < 0)
    {
        log<level::ERR>(format("SocketManager::SendDatagram: Couldn't sendto "
                               "socket (IPv6): {}",
                               std::strerror(errno))
                            .c_str());
    }

    // Send serialized data (v4)
    auto addr4 = reinterpret_cast<const sockaddr*>(&bcast->destination);
    err = sendto(fd, serialized.c_str(), serialized.length(), 0, addr4,
                 sizeof(bcast->destination));
    if (err < 0)
    {
        log<level::ERR>(format("SocketManager::SendDatagram: Couldn't sendto "
                               "socket (IPv4): {}",
                               std::strerror(errno))
                            .c_str());
    }

    CloseSocketSafely(fd);
}

void SocketManager::CloseSocketSafely(int fd)
{
    std::lock_guard<std::mutex> lock(open_sockets_lock_);
    if (open_sockets_.find(fd) != open_sockets_.end())
    {
        close(fd);
        open_sockets_.erase(fd);
    }
}

void SocketManager::TrackSocket(int fd)
{
    std::lock_guard<std::mutex> lock(open_sockets_lock_);
    open_sockets_.insert(fd);
}
