#include "MCTPEndpoint.hpp"

#include "Utils.hpp"
#include "VariantVisitors.hpp"

#include <bits/fs_dir.h>

#include <boost/system/detail/errc.hpp>
#include <phosphor-logging/lg2.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/bus.hpp>
#include <sdbusplus/bus/match.hpp>
#include <sdbusplus/exception.hpp>
#include <sdbusplus/message.hpp>
#include <sdbusplus/message/native_types.hpp>

#include <array>
#include <cassert>
#include <charconv>
#include <cstddef>
#include <cstdint>
#include <exception>
#include <filesystem>
#include <format>
#include <fstream>
#include <functional>
#include <iterator>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <set>
#include <span>
#include <stdexcept>
#include <string>
#include <string_view>
#include <system_error>
#include <utility>
#include <variant>
#include <vector>

PHOSPHOR_LOG2_USING;

static constexpr const char* mctpdBusName = "au.com.codeconstruct.MCTP1";
static constexpr const char* mctpdControlPath = "/au/com/codeconstruct/mctp1";
static constexpr const char* mctpdControlInterface =
    "au.com.codeconstruct.MCTP.BusOwner1";
static constexpr const char* mctpdEndpointControlInterface =
    "au.com.codeconstruct.MCTP.Endpoint1";

MCTPDDevice::MCTPDDevice(
    const std::shared_ptr<sdbusplus::asio::connection>& connection,
    const std::string& interface, const std::vector<uint8_t>& physaddr) :
    connection(connection), interface(interface), physaddr(physaddr)
{}

void MCTPDDevice::onEndpointInterfacesRemoved(
    const std::weak_ptr<MCTPDDevice>& weak, const std::string& objpath,
    sdbusplus::message_t& msg)
{
    auto path = msg.unpack<sdbusplus::object_path>();
    assert(path.string() == objpath);

    auto removedIfaces = msg.unpack<std::set<std::string>>();
    if (!removedIfaces.contains(mctpdEndpointControlInterface))
    {
        return;
    }

    if (auto self = weak.lock())
    {
        self->endpointRemoved();
    }
    else
    {
        info(
            "Device for inventory at '{INVENTORY_PATH}' was destroyed concurrent to endpoint removal",
            "INVENTORY_PATH", objpath);
    }
}

void MCTPDDevice::finaliseEndpoint(
    const std::string& objpath, uint8_t eid, int network,
    std::function<void(const std::error_code& ec,
                       const std::shared_ptr<MCTPEndpoint>& ep)>& added)
{
    const auto matchSpec =
        sdbusplus::match_rules::interfacesRemovedAtPath(objpath);
    removeMatch = std::make_unique<sdbusplus::match>(
        *connection, matchSpec,
        std::bind_front(MCTPDDevice::onEndpointInterfacesRemoved,
                        weak_from_this(), objpath));
    endpoint = std::make_shared<MCTPDEndpoint>(shared_from_this(), connection,
                                               objpath, network, eid);
    added({}, endpoint);
}

void MCTPDDevice::setup(
    std::function<void(const std::error_code& ec,
                       const std::shared_ptr<MCTPEndpoint>& ep)>&& added)
{
    // Use a lambda to separate state validation from business logic,
    // where the business logic for a successful setup() is encoded in
    // MctpdDevice::finaliseEndpoint()
    auto onSetup = [weak{weak_from_this()}, added{std::move(added)}](
                       const boost::system::error_code& ec, uint8_t eid,
                       int network, const std::string& objpath,
                       bool allocated [[maybe_unused]]) mutable {
        if (ec)
        {
            added(ec, {});
            return;
        }

        if (auto self = weak.lock())
        {
            self->finaliseEndpoint(objpath, eid, network, added);
        }
        else
        {
            info(
                "Device object for inventory at '{INVENTORY_PATH}' was destroyed concurrent to completion of its endpoint setup",
                "INVENTORY_PATH", objpath);
        }
    };
    connection->async_method_call(
        onSetup, mctpdBusName,
        mctpdControlPath + std::string("/interfaces/") + interface,
        mctpdControlInterface, "AssignEndpoint", physaddr);
}

void MCTPDDevice::endpointRemoved()
{
    if (endpoint)
    {
        debug("Endpoint removed @ [ {MCTP_ENDPOINT} ]", "MCTP_ENDPOINT",
              endpoint->describe());
        removeMatch.reset();
        endpoint->removed();
        endpoint.reset();
    }
}

void MCTPDDevice::remove()
{
    if (endpoint)
    {
        debug("Removing endpoint @ [ {MCTP_ENDPOINT} ]", "MCTP_ENDPOINT",
              endpoint->describe());
        endpoint->remove();
    }
}

std::string MCTPDDevice::describe() const
{
    std::string description = std::format("interface: {}", interface);
    if (!physaddr.empty())
    {
        description.append(", address: 0x [ ");
        auto it = physaddr.begin();
        for (; it != physaddr.end() - 1; it++)
        {
            description.append(std::format("{:02x} ", *it));
        }
        description.append(std::format("{:02x} ]", *it));
    }
    return description;
}

// https://en.cppreference.com/w/cpp/utility/hash/operator().html
//
// https://en.wikipedia.org/w/index.php?title=Fowler%E2%80%93Noll%E2%80%93Vo_hash_function&oldid=1312413750#FNV_hash_parameters
template <typename T, typename V, T p>
static std::size_t fnv1a(T h, V e);

template <std::size_t S>
static std::size_t fnv1a(const std::vector<std::uint8_t>& d);

template <typename V>
static std::size_t fnv1a(std::uint32_t h, V v)
{
    constexpr std::uint32_t p = 0x01000193;
    return (h ^ v) * p;
}

template <>
[[maybe_unused]] std::size_t fnv1a<4UL>(const std::vector<std::uint8_t>& d)
{
    std::uint32_t h = 0x811c9dc5;
    for (const auto& v : d)
    {
        h = fnv1a(h, v);
    }
    return h;
}

template <typename V>
static std::size_t fnv1a(std::uint64_t h, V v)
{
    constexpr std::uint64_t p = 0x00000100000001b3;
    return (h ^ v) * p;
}

template <>
[[maybe_unused]] std::size_t fnv1a<8UL>(const std::vector<std::uint8_t>& d)
{
    std::uint64_t h = 0xcbf29ce484222325;
    for (const auto& v : d)
    {
        h = fnv1a(h, v);
    }
    return h;
}

static std::size_t fnv1aHash(const std::vector<std::uint8_t>& d)
{
    return fnv1a<sizeof(std::size_t)>(d);
}

std::size_t MCTPDDevice::id() const
{
    std::size_t h1 = std::hash<std::string>{}(interface);
    std::size_t h2 = fnv1aHash(physaddr);

    return h1 ^ (h2 << 1);
}

std::string MCTPDEndpoint::path(const std::shared_ptr<MCTPEndpoint>& ep)
{
    return std::format("{}/networks/{}/endpoints/{}", mctpdControlPath,
                       ep->network(), ep->eid());
}

void MCTPDEndpoint::onMctpEndpointChange(sdbusplus::message_t& msg)
{
    auto [iface, changed, _] =
        msg.unpack<std::string, std::map<std::string, BasicVariantType>,
                   std::vector<std::string>>();
    if (iface != mctpdEndpointControlInterface)
    {
        return;
    }

    auto it = changed.find("Connectivity");
    if (it == changed.end())
    {
        return;
    }

    updateEndpointConnectivity(std::get<std::string>(it->second));
}

void MCTPDEndpoint::updateEndpointConnectivity(const std::string& connectivity)
{
    if (connectivity == "Degraded")
    {
        if (notifyDegraded)
        {
            notifyDegraded(shared_from_this());
        }
    }
    else if (connectivity == "Available")
    {
        if (notifyAvailable)
        {
            notifyAvailable(shared_from_this());
        }
    }
    else
    {
        debug("Unrecognised connectivity state: '{CONNECTIVITY_STATE}'",
              "CONNECTIVITY_STATE", connectivity);
    }
}

int MCTPDEndpoint::network() const
{
    return mctp.network;
}

uint8_t MCTPDEndpoint::eid() const
{
    return mctp.eid;
}

void MCTPDEndpoint::subscribe(Event&& degraded, Event&& available,
                              Event&& removed)
{
    const auto matchSpec = sdbusplus::match_rules::propertiesChangedNamespace(
        objpath.string(), mctpdEndpointControlInterface);

    this->notifyDegraded = std::move(degraded);
    this->notifyAvailable = std::move(available);
    this->notifyRemoved = std::move(removed);

    try
    {
        connectivityMatch.emplace(
            static_cast<sdbusplus::bus_t&>(*connection), matchSpec,
            [weak{weak_from_this()},
             path{objpath.string()}](sdbusplus::message_t& msg) {
                if (auto self = weak.lock())
                {
                    self->onMctpEndpointChange(msg);
                }
                else
                {
                    info(
                        "The endpoint for the device at inventory path '{INVENTORY_PATH}' was destroyed concurrent to the removal of its state change match",
                        "INVENTORY_PATH", path);
                }
            });
        connection->async_method_call(
            [weak{weak_from_this()},
             path{objpath.string()}](const boost::system::error_code& ec,
                                     const std::variant<std::string>& value) {
                if (ec)
                {
                    debug(
                        "Failed to get current connectivity state: {ERROR_MESSAGE}",
                        "ERROR_MESSAGE", ec.message(), "ERROR_CATEGORY",
                        ec.category().name(), "ERROR_CODE", ec.value());
                    return;
                }

                if (auto self = weak.lock())
                {
                    const std::string& connectivity =
                        std::get<std::string>(value);
                    self->updateEndpointConnectivity(connectivity);
                }
                else
                {
                    info(
                        "The endpoint for the device at inventory path '{INVENTORY_PATH}' was destroyed concurrent to the completion of its connectivity state query",
                        "INVENTORY_PATH", path);
                }
            },
            mctpdBusName, objpath.string(), "org.freedesktop.DBus.Properties",
            "Get", mctpdEndpointControlInterface, "Connectivity");
    }
    catch (const sdbusplus::exception::internal_exception& err)
    {
        this->notifyDegraded = nullptr;
        this->notifyAvailable = nullptr;
        this->notifyRemoved = nullptr;
        std::throw_with_nested(
            MCTPException("Failed to register connectivity signal match"));
    }
}

void MCTPDEndpoint::remove()
{
    connection->async_method_call(
        [self{shared_from_this()}](const boost::system::error_code& ec) {
            if (ec)
            {
                debug("Failed to remove endpoint @ [ {MCTP_ENDPOINT} ]",
                      "MCTP_ENDPOINT", self->describe());
                return;
            }
        },
        mctpdBusName, objpath.string(), mctpdEndpointControlInterface,
        "Remove");
}

void MCTPDEndpoint::removed()
{
    if (notifyRemoved)
    {
        notifyRemoved(shared_from_this());
    }
}

std::string MCTPDEndpoint::describe() const
{
    return std::format("network: {}, EID: {} | {}", mctp.network, mctp.eid,
                       dev->describe());
}

std::shared_ptr<MCTPDevice> MCTPDEndpoint::device() const
{
    return dev;
}

std::optional<SensorBaseConfigMap> I2CMCTPDDevice::match(
    const SensorData& config)
{
    auto iface = config.find(configInterfaceName(configType));
    if (iface == config.end())
    {
        return std::nullopt;
    }
    return iface->second;
}

std::optional<SensorBaseConfigMap> I3CMCTPDDevice::match(
    const SensorData& config)
{
    auto iface = config.find(configInterfaceName(configType));
    if (iface == config.end())
    {
        return std::nullopt;
    }
    return iface->second;
}

bool I2CMCTPDDevice::match(const std::set<std::string>& interfaces)
{
    return interfaces.contains(configInterfaceName(configType));
}

bool I3CMCTPDDevice::match(const std::set<std::string>& interfaces)
{
    return interfaces.contains(configInterfaceName(configType));
}

std::shared_ptr<I2CMCTPDDevice> I2CMCTPDDevice::from(
    const std::shared_ptr<sdbusplus::asio::connection>& connection,
    const SensorBaseConfigMap& iface)
{
    auto mType = iface.find("Type");
    if (mType == iface.end())
    {
        throw std::invalid_argument(
            "No 'Type' member found for provided configuration object");
    }

    auto type = std::visit(VariantToStringVisitor(), mType->second);
    if (type != configType)
    {
        throw std::invalid_argument("Not an SMBus device");
    }

    auto mAddress = iface.find("Address");
    auto mBus = iface.find("Bus");
    auto mName = iface.find("Name");
    if (mAddress == iface.end() || mBus == iface.end() || mName == iface.end())
    {
        throw std::invalid_argument(
            "Configuration object violates MCTPI2CTarget schema");
    }

    auto sAddress = std::visit(VariantToStringVisitor(), mAddress->second);
    std::uint8_t address{};
    auto [aptr, aec] = std::from_chars(
        sAddress.data(), sAddress.data() + sAddress.size(), address);
    if (aec != std::errc{})
    {
        throw std::invalid_argument("Bad device address");
    }

    auto sBus = std::visit(VariantToStringVisitor(), mBus->second);
    int bus{};
    auto [bptr,
          bec] = std::from_chars(sBus.data(), sBus.data() + sBus.size(), bus);
    if (bec != std::errc{})
    {
        throw std::invalid_argument("Bad bus index");
    }

    try
    {
        return std::make_shared<I2CMCTPDDevice>(connection, bus, address);
    }
    catch (const MCTPException& ex)
    {
        warning(
            "Failed to create I2CMCTPDDevice at [ bus: {I2C_BUS}, address: {I2C_ADDRESS} ]: {EXCEPTION}",
            "I2C_BUS", bus, "I2C_ADDRESS", address, "EXCEPTION", ex);
        return {};
    }
}

std::shared_ptr<I3CMCTPDDevice> I3CMCTPDDevice::from(
    const std::shared_ptr<sdbusplus::asio::connection>& connection,
    const SensorBaseConfigMap& iface)
{
    auto mType = iface.find("Type");
    if (mType == iface.end())
    {
        throw std::invalid_argument(
            "No 'Type' member found for provided configuration object");
    }

    auto type = std::visit(VariantToStringVisitor(), mType->second);
    if (type != configType)
    {
        throw std::invalid_argument("Not an I3C device");
    }

    auto mAddress = iface.find("Address");
    auto mBus = iface.find("Bus");
    auto mName = iface.find("Name");
    if (mAddress == iface.end() || mBus == iface.end() || mName == iface.end())
    {
        throw std::invalid_argument(
            "Configuration object violates MCTPI3CTarget schema");
    }

    auto address = std::visit(VariantToNumArrayVisitor<uint8_t, uint64_t>(),
                              mAddress->second);
    if (address.empty())
    {
        throw std::invalid_argument("Bad device address");
    }

    auto sBus = std::visit(VariantToStringVisitor(), mBus->second);
    int bus{};
    auto [bptr,
          bec] = std::from_chars(sBus.data(), sBus.data() + sBus.size(), bus);
    if (bec != std::errc{})
    {
        throw std::invalid_argument("Bad bus index");
    }

    try
    {
        return std::make_shared<I3CMCTPDDevice>(connection, bus, address);
    }
    catch (const MCTPException& ex)
    {
        warning(
            "Failed to create I3CMCTPDDevice at [ bus: {I3C_BUS} ]: {EXCEPTION}",
            "I3C_BUS", bus, "EXCEPTION", ex);
        return {};
    }
}

std::string I2CMCTPDDevice::interfaceFromBus(int bus)
{
    std::filesystem::path netdir =
        std::format("/sys/bus/i2c/devices/i2c-{}/net", bus);
    std::error_code ec;
    std::filesystem::directory_iterator it(netdir, ec);
    if (ec || it == std::filesystem::end(it))
    {
        error("No net device associated with I2C bus {I2C_BUS} at {NET_DEVICE}",
              "I2C_BUS", bus, "NET_DEVICE", netdir);
        throw MCTPException("Bus is not configured as an MCTP interface");
    }

    return it->path().filename();
}

std::string I3CMCTPDDevice::interfaceFromBus(int bus)
{
    std::filesystem::path netdir = std::format("/sys/devices/virtual/net");
    std::error_code ec;
    std::filesystem::directory_iterator it(netdir, ec);
    if (ec || it == std::filesystem::end(it))
    {
        error("No net device associated with I3C bus {I3C_BUS} at {NET_DEVICE}",
              "I3C_BUS", bus, "NET_DEVICE", netdir);
        throw MCTPException("Bus is not configured as an MCTP interface");
    }

    std::string targetInterface = std::format("mctpi3c{}", bus);
    for (const auto& entry : std::filesystem::directory_iterator(netdir))
    {
        if (entry.is_directory() && entry.path().filename() == targetInterface)
        {
            return targetInterface;
        }
    }

    error("No matching net device found for I3C bus {I3C_BUS} at {NET_DEVICE}",
          "I3C_BUS", bus, "NET_DEVICE", netdir);
    throw MCTPException("No matching net device found for the specified bus");
}

// The addresses of the USB host controllers belong to the SOC, so a root hub
// position only names one once the SOC is known.
static std::span<const std::string_view> rootHubsForSoc(
    const std::string& socFamily)
{
    // The AST2620 is the AST2600 with the same controller addresses. The UHCI
    // companion at 1e6b0000 is not listed: it serves the same ports at lower
    // speed rather than being a host controller of its own.
    static constexpr std::array<std::string_view, 2> ast2600RootHubs = {
        "/sys/devices/platform/ahb/1e6a1000.usb",
        "/sys/devices/platform/ahb/1e6a3000.usb"};

    if (socFamily.find("AST2600") != std::string::npos ||
        socFamily.find("AST2620") != std::string::npos)
    {
        return ast2600RootHubs;
    }

    return {};
}

// Resolve a root hub position to its host controller's sysfs path. Returns
// nullopt, having logged why, if the SOC or the position is not supported.
static std::optional<std::string_view> rootHubPathForPosition(size_t position)
{
    std::ifstream socFamilyFile("/sys/bus/soc/devices/soc0/family");
    if (!socFamilyFile)
    {
        error("Unable to read SOC family information");
        return std::nullopt;
    }
    std::string socFamily;
    std::getline(socFamilyFile, socFamily);

    const std::span<const std::string_view> rootHubs =
        rootHubsForSoc(socFamily);
    if (rootHubs.empty())
    {
        error("Unsupported SOC for USB MCTP: {SOC_FAMILY}", "SOC_FAMILY",
              socFamily);
        return std::nullopt;
    }

    if (position >= rootHubs.size())
    {
        error(
            "RootHubPosition {POSITION} names no host controller on {SOC_FAMILY}",
            "POSITION", position, "SOC_FAMILY", socFamily);
        return std::nullopt;
    }

    return rootHubs[position];
}

/*
 * Given the sysfs path for a USB root hub, determines the bus number. An
 * example root hub path on an AST2600 is
 * /sys/devices/platform/ahb/1e6a3000.usb. This function identifies the
 * correct bus device directory (e.g. "usb1") by looking for a "busnum"
 * attribute file within it, and returns the content of that file.
 */
std::string USBMCTPDDevice::busFromRootHubPath(
    const std::filesystem::path& rootHubPath)
{
    std::error_code ec;
    std::filesystem::directory_iterator it(rootHubPath, ec);
    if (ec)
    {
        error("Unable to open RootHubPath {PATH}", "PATH", rootHubPath);
        throw MCTPException("Invalid RootHubPath");
    }

    for (const auto& entry : it)
    {
        const auto& path = entry.path();
        if (!entry.is_directory() ||
            !path.filename().string().starts_with("usb"))
        {
            continue;
        }

        std::filesystem::path busnumPath = path / "busnum";
        if (!std::filesystem::exists(busnumPath))
        {
            continue;
        }
        std::ifstream busnumFile(busnumPath);
        std::string busnum;
        if (busnumFile >> busnum && !busnum.empty())
        {
            return busnum;
        }
    }

    error(
        "No directory containing a 'busnum' file found under RootHubPath {PATH}",
        "PATH", rootHubPath);
    throw MCTPException("Could not determine bus number");
}

/*
 * Given the components of a USB device's sysfs path, construct the full path
 * and determine the network interface name associated with it.
 */
std::string USBMCTPDDevice::interfaceFromSysfs(
    const std::string& bus, const std::string& port, uint8_t configuration,
    uint8_t interfaceNum)
{
    std::filesystem::path netdir =
        std::format("/sys/bus/usb/devices/{}-{}/{}-{}:{}.{}/net", bus, port,
                    bus, port, configuration, interfaceNum);
    std::error_code ec;
    std::filesystem::directory_iterator it(netdir, ec);
    if (ec || it == std::filesystem::end(it))
    {
        error("No net device associated with USB device at {NET_DEVICE}",
              "NET_DEVICE", netdir);
        throw MCTPException("Device is not configured as an MCTP interface");
    }

    return it->path().filename();
}

std::optional<SensorBaseConfigMap> USBMCTPDDevice::match(
    const SensorData& config)
{
    auto iface = config.find(configInterfaceName(configType));
    if (iface == config.end())
    {
        return std::nullopt;
    }
    return iface->second;
}

bool USBMCTPDDevice::match(const std::set<std::string>& interfaces)
{
    return interfaces.contains(configInterfaceName(configType));
}

std::shared_ptr<USBMCTPDDevice> USBMCTPDDevice::from(
    const std::shared_ptr<sdbusplus::asio::connection>& connection,
    const SensorBaseConfigMap& iface)
{
    auto mName = iface.find("Name");
    auto mType = iface.find("Type");
    if (mType == iface.end())
    {
        throw std::invalid_argument(
            "No 'Type' member found for provided configuration object");
    }

    auto type = std::visit(VariantToStringVisitor(), mType->second);
    if (type != configType)
    {
        throw std::invalid_argument("Not an USB device");
    }

    auto mRootHubPosition = iface.find("RootHubPosition");
    auto mPort = iface.find("Port");
    auto mConfiguration = iface.find("Configuration");
    auto mInterface = iface.find("Interface");

    if (mName == iface.end() || mRootHubPosition == iface.end() ||
        mPort == iface.end() || mConfiguration == iface.end() ||
        mInterface == iface.end())
    {
        throw std::invalid_argument(
            "Configuration object violates MCTPUSBDevice schema");
    }

    auto sRootHubPosition =
        std::visit(VariantToStringVisitor(), mRootHubPosition->second);
    uint8_t rootHubPosition{};
    auto [rptr, rec] = std::from_chars(
        sRootHubPosition.data(),
        sRootHubPosition.data() + sRootHubPosition.size(), rootHubPosition);
    if (rec != std::errc{} ||
        rptr != sRootHubPosition.data() + sRootHubPosition.size())
    {
        throw std::invalid_argument("Bad RootHubPosition value");
    }

    auto portArray = std::visit(VariantToNumArrayVisitor<uint8_t, uint64_t>(),
                                mPort->second);
    if (portArray.empty())
    {
        throw std::invalid_argument("Bad Port value");
    }

    // Convert port array to dot-separated string (e.g., [1, 2, 1] -> "1.2.1")
    std::string port = std::accumulate(
        std::next(portArray.begin()), portArray.end(),
        std::to_string(portArray[0]), [](const std::string& acc, uint8_t val) {
            return acc + "." + std::to_string(val);
        });

    auto sConfiguration =
        std::visit(VariantToStringVisitor(), mConfiguration->second);
    uint8_t configuration{};
    auto [cptr, cec] = std::from_chars(
        sConfiguration.data(), sConfiguration.data() + sConfiguration.size(),
        configuration);
    if (cec != std::errc{} ||
        cptr != sConfiguration.data() + sConfiguration.size())
    {
        throw std::invalid_argument("Bad Configuration value");
    }

    auto sInterface = std::visit(VariantToStringVisitor(), mInterface->second);
    uint8_t interfaceNum{};
    auto [iptr, iec] = std::from_chars(
        sInterface.data(), sInterface.data() + sInterface.size(), interfaceNum);
    if (iec != std::errc{} || iptr != sInterface.data() + sInterface.size())
    {
        throw std::invalid_argument("Bad Interface value");
    }

    std::optional<std::string_view> rootHubPath =
        rootHubPathForPosition(rootHubPosition);
    if (!rootHubPath)
    {
        return {};
    }

    try
    {
        std::string bus = busFromRootHubPath(std::string(*rootHubPath));
        std::string interface =
            interfaceFromSysfs(bus, port, configuration, interfaceNum);
        return std::make_shared<USBMCTPDDevice>(connection, interface);
    }
    catch (const MCTPException& ex)
    {
        warning(
            "Failed to create MCTPUSBDevice at [ RootHubPosition: {POSITION}, port: {USB_PORT} ]: {EXCEPTION}",
            "POSITION", sRootHubPosition, "USB_PORT", port, "EXCEPTION", ex);
        return {};
    }
}
