/*
 // Copyright (c) 2018 Intel Corporation
 //
 // 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.
 */
#pragma once

#include "dbus_singleton.hpp"
#include "logging.hpp"

#include <boost/system/error_code.hpp> // IWYU pragma: keep
#include <mapper/mapper.hpp>
#include <sdbusplus/asio/property.hpp>
#include <sdbusplus/message/native_types.hpp>

#include <array>
#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <functional>
#include <regex>
#include <span>
#include <sstream>
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>

// IWYU pragma: no_include <stddef.h>
// IWYU pragma: no_include <stdint.h>
// IWYU pragma: no_include <boost/system/detail/error_code.hpp>

namespace dbus
{

namespace utility
{

// clang-format off
using DbusVariantType = std::variant<
    std::vector<std::tuple<std::string, std::string, std::string>>,
    std::vector<std::string>,
    std::vector<double>,
    std::string,
    int64_t,
    uint64_t,
    double,
    int32_t,
    uint32_t,
    int16_t,
    uint16_t,
    uint8_t,
    bool,
    sdbusplus::message::unix_fd,
    std::vector<uint32_t>,
    std::vector<uint16_t>,
    sdbusplus::message::object_path,
    std::tuple<uint64_t, std::vector<std::tuple<std::string, std::string, double, uint64_t>>>,
    std::vector<std::tuple<std::string, std::string>>,
    std::vector<std::tuple<uint32_t, std::vector<uint32_t>>>,
    std::vector<std::tuple<uint32_t, size_t>>,
    std::vector<std::tuple<sdbusplus::message::object_path, std::string,
                           std::string, std::string>>
 >;

// clang-format on
using DBusPropertiesMap = std::vector<std::pair<std::string, DbusVariantType>>;
using DBusInteracesMap = std::vector<std::pair<std::string, DBusPropertiesMap>>;
using ManagedObjectType =
    std::vector<std::pair<sdbusplus::message::object_path, DBusInteracesMap>>;

// Map of service name to list of interfaces
using MapperServiceMap =
    std::vector<std::pair<std::string, std::vector<std::string>>>;

// Map of object paths to MapperServiceMaps
using MapperGetSubTreeResponse =
    std::vector<std::pair<std::string, MapperServiceMap>>;

using MapperGetObject =
    std::vector<std::pair<std::string, std::vector<std::string>>>;

using MapperGetAncestorsResponse = std::vector<
    std::pair<std::string,
              std::vector<std::pair<std::string, std::vector<std::string>>>>>;

using MapperGetSubTreePathsResponse = std::vector<std::string>;

using MapperEndPoints = std::vector<std::string>;

inline void escapePathForDbus(std::string& path)
{
    const static std::regex reg("[^A-Za-z0-9_/]");
    std::regex_replace(path.begin(), path.begin(), path.end(), reg, "_");
}

inline void logError(const boost::system::error_code& ec)
{
    if (ec)
    {
        BMCWEB_LOG_ERROR << "DBus error: " << ec << ", cannot call method";
    }
}

// gets the string N strings deep into a path
// i.e.  /0th/1st/2nd/3rd
inline bool getNthStringFromPath(const std::string& path, int index,
                                 std::string& result)
{
    if (index < 0)
    {
        return false;
    }

    std::filesystem::path p1(path);
    int count = -1;
    for (auto const& element : p1)
    {
        if (element.has_filename())
        {
            ++count;
            if (count == index)
            {
                result = element.stem().string();
                break;
            }
        }
    }
    return count >= index;
}

template <typename Callback>
inline void checkDbusPathExists(const std::string& path, Callback&& callback)
{
    crow::connections::systemBus->async_method_call(
        [callback{std::forward<Callback>(callback)}](
            const boost::system::error_code& ec,
            const dbus::utility::MapperGetObject& objectNames) {
        callback(!ec && !objectNames.empty());
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetObject", path,
        std::array<std::string, 0>());
}

inline InterfaceMapType interfaceMap;

namespace dbus_mapper
{
inline void
    getSubTree(const std::string& path, int32_t depth,
               std::span<const std::string_view> interfaces,
               std::function<void(const boost::system::error_code&,
                                  const MapperGetSubTreeResponse&)>&& callback)
{
    crow::connections::systemBus->async_method_call(
        [callback{std::move(callback)}](
            const boost::system::error_code& ec,
            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth,
        interfaces);
}

// Overload to support span of strings for interface names.
inline void
    getSubTree(const std::string& path, int32_t depth,
               std::span<std::string> interfaces,
               std::function<void(const boost::system::error_code&,
                                  const MapperGetSubTreeResponse&)>&& callback)
{
    crow::connections::systemBus->async_method_call(
        [callback{std::move(callback)}](
            const boost::system::error_code& ec,
            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTree", path, depth,
        interfaces);
}

inline void getSubTreePaths(
    const std::string& path, int32_t depth,
    std::span<const std::string_view> interfaces,
    std::function<void(const boost::system::error_code&,
                       const MapperGetSubTreePathsResponse&)>&& callback)
{
    crow::connections::systemBus->async_method_call(
        [callback{std::move(callback)}](
            const boost::system::error_code& ec,
            const MapperGetSubTreePathsResponse& subtreePaths) {
        callback(ec, subtreePaths);
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", path, depth,
        interfaces);
}

inline void getAssociatedSubTree(
    const sdbusplus::message::object_path& associatedPath,
    const sdbusplus::message::object_path& path, int32_t depth,
    std::span<const std::string_view> interfaces,
    std::function<void(const boost::system::error_code&,
                       const MapperGetSubTreeResponse&)>&& callback)
{
    crow::connections::systemBus->async_method_call(
        [callback{std::move(callback)}](
            const boost::system::error_code& ec,
            const MapperGetSubTreeResponse& subtree) { callback(ec, subtree); },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTree",
        associatedPath, path, depth, interfaces);
}

inline void getAssociatedSubTreePaths(
    const sdbusplus::message::object_path& associatedPath,
    const sdbusplus::message::object_path& path, int32_t depth,
    std::span<const std::string_view> interfaces,
    std::function<void(const boost::system::error_code&,
                       const MapperGetSubTreePathsResponse&)>&& callback)
{
    crow::connections::systemBus->async_method_call(
        [callback{std::move(callback)}](
            const boost::system::error_code& ec,
            const MapperGetSubTreePathsResponse& subtreePaths) {
        callback(ec, subtreePaths);
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetAssociatedSubTreePaths",
        associatedPath, path, depth, interfaces);
}

inline void
    getDbusObject(const std::string& path,
                  std::span<const std::string_view> interfaces,
                  std::function<void(const boost::system::error_code&,
                                     const MapperGetObject&)>&& callback)
{
    crow::connections::systemBus->async_method_call(
        [callback{std::move(callback)}](const boost::system::error_code& ec,
                                        const MapperGetObject& object) {
        callback(ec, object);
        },
        "xyz.openbmc_project.ObjectMapper",
        "/xyz/openbmc_project/object_mapper",
        "xyz.openbmc_project.ObjectMapper", "GetObject", path, interfaces);
}
} // namespace dbus_mapper

// Ideally this would be a class variable.
inline bool isMapperLiteEnabled()
{
    return !interfaceMap.empty();
}

inline void
    getSubTree(const std::string& path, int32_t depth,
               std::span<const std::string_view> interfaces,
               std::function<void(const boost::system::error_code&,
                                  const MapperGetSubTreeResponse&)>&& callback)
{
    if (!isMapperLiteEnabled())
    {
        dbus_mapper::getSubTree(path, depth, interfaces, std::move(callback));
        return;
    }
    BMCWEB_LOG_DEBUG << "Mapper lite getSubTree called interfaceMap.size()="
                     << interfaceMap.size();
    std::vector<std::string> interfaces2;
    for (auto& s : interfaces)
    {
        interfaces2.emplace_back(s);
    }
    std::vector<InterfaceMapType::value_type> out =
        ::getSubTree(interfaceMap, path, depth, interfaces2);

    MapperGetSubTreeResponse out2;
    for (const auto& connection : out)
    {
        auto& newConnections = out2.emplace_back(std::make_pair(
            connection.first,
            MapperGetSubTreeResponse::value_type::second_type{}));
        for (const auto& path2 : connection.second)
        {
            auto& newPath = newConnections.second.emplace_back(
                path2.first, MapperGetSubTreeResponse::value_type::second_type::
                                 value_type::second_type{});
            for (const auto& interface2 : path2.second)
            {
                newPath.second.emplace_back(interface2);
            }
        }
    }

    boost::system::error_code ec;

#ifdef BMCWEB_STATEFUL_CHECK_RESPONSE
    dbus_mapper::getSubTree(path, depth, interfaces,
                            [out2](const boost::system::error_code& ec,
                                   const MapperGetSubTreeResponse& out) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Mapper returned an error " << ec.message();
            return;
        }
        if (out != out2)
        {
            BMCWEB_LOG_CRITICAL << "Dbus GetSubTree doesn't match mapper lite";
        }
        else
        {
            BMCWEB_LOG_DEBUG << "Dbus GetSubTree matched mapper lite";
        }
    });
#endif

    callback(ec, out2);
}

// Overload to support span of strings for interface names.
inline void
    getSubTree(const std::string& path, int32_t depth,
               std::span<std::string> interfaces,
               std::function<void(const boost::system::error_code&,
                                  const MapperGetSubTreeResponse&)>&& callback)
{
    std::vector<std::string_view> interfacesSpan;
    for (const auto& interface : interfaces)
    {
        interfacesSpan.emplace_back(interface);
    }
    getSubTree(path, depth, interfacesSpan, std::move(callback));
}
inline void getSubTreePaths(
    const std::string& path, int32_t depth,
    std::span<const std::string_view> interfaces,
    std::function<void(const boost::system::error_code&,
                       const MapperGetSubTreePathsResponse&)>&& callback)
{
    if (!isMapperLiteEnabled())
    {
        dbus_mapper::getSubTreePaths(path, depth, interfaces,
                                     std::move(callback));
        return;
    }
    BMCWEB_LOG_DEBUG
        << "Mapper lite getSubTreePaths called interfaceMap.size()="
        << interfaceMap.size();
    std::vector<std::string> interfaces2;
    for (auto& s : interfaces)
    {
        interfaces2.emplace_back(s);
    }
    MapperGetSubTreePathsResponse out2 =
        ::getSubTreePaths(interfaceMap, path, depth, interfaces2);

#ifdef BMCWEB_STATEFUL_CHECK_RESPONSE
    dbus_mapper::getSubTreePaths(
        path, depth, interfaces,
        [out2](const boost::system::error_code& ec,
               const MapperGetSubTreePathsResponse& out) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Mapper returned an error " << ec.message();
            return;
        }
        if (out != out2)
        {
            BMCWEB_LOG_CRITICAL
                << "Dbus GetSubTreePaths doesn't match mapper lite";
        }
        else
        {
            BMCWEB_LOG_DEBUG << "Dbus GetSubTreePaths matched mapper lite";
        }
        });
#endif

    boost::system::error_code ec;
    callback(ec, out2);
}

inline void getAssociatedSubTree(
    const sdbusplus::message::object_path& associatedPath,
    const sdbusplus::message::object_path& path, int32_t depth,
    std::span<const std::string_view> interfaces,
    std::function<void(const boost::system::error_code&,
                       const MapperGetSubTreeResponse&)>&& callback)
{
    if (!isMapperLiteEnabled())
    {
        dbus_mapper::getAssociatedSubTree(associatedPath, path, depth,
                                          interfaces, std::move(callback));
        return;
    }
    BMCWEB_LOG_DEBUG
        << "Mapper lite getSubTreePaths called interfaceMap.size()="
        << interfaceMap.size();
    std::vector<std::string> interfaces2;
    for (auto& s : interfaces)
    {
        interfaces2.emplace_back(s);
    }
    std::vector<InterfaceMapType::value_type> out =
        ::getAssociatedSubTree(interfaceMap, associationMaps, associatedPath,
                               path, depth, interfaces2);
    MapperGetSubTreeResponse out2;
    for (const auto& connection : out)
    {
        auto& newConnections = out2.emplace_back(std::make_pair(
            connection.first,
            MapperGetSubTreeResponse::value_type::second_type{}));
        for (const auto& path2 : connection.second)
        {
            auto& newPath = newConnections.second.emplace_back(
                path2.first, MapperGetSubTreeResponse::value_type::second_type::
                                 value_type::second_type{});
            for (const auto& interface2 : path2.second)
            {
                newPath.second.emplace_back(interface2);
            }
        }
    }
#ifdef BMCWEB_STATEFUL_CHECK_RESPONSE
    dbus_mapper::getAssociatedSubTree(
        associatedPath, path, depth, interfaces,
        [out2](const boost::system::error_code& ec,
               const MapperGetSubTreeResponse& out) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Mapper returned an error " << ec.message();
            return;
        }
        if (out != out2)
        {
            BMCWEB_LOG_CRITICAL
                << "Dbus GetAssociatedSubTree doesn't match mapper lite";
        }
        else
        {
            BMCWEB_LOG_DEBUG << "Dbus GetAssociatedSubTree matched mapper lite";
        }
        });
#endif

    boost::system::error_code ec;
    callback(ec, out2);
}

inline void getAssociatedSubTreePaths(
    const sdbusplus::message::object_path& associatedPath,
    const sdbusplus::message::object_path& path, int32_t depth,
    std::span<const std::string_view> interfaces,
    std::function<void(const boost::system::error_code&,
                       const MapperGetSubTreePathsResponse&)>&& callback)
{
    if (!isMapperLiteEnabled())
    {
        dbus_mapper::getAssociatedSubTreePaths(associatedPath, path, depth,
                                               interfaces, std::move(callback));
        return;
    }
    BMCWEB_LOG_DEBUG
        << "Mapper lite getAssociatedSubTreePaths called interfaceMap.size()="
        << interfaceMap.size();
    std::vector<std::string> interfaces2;
    for (auto& s : interfaces)
    {
        interfaces2.emplace_back(s);
    }
    MapperGetSubTreePathsResponse out2 =
        ::getAssociatedSubTreePaths(interfaceMap, associationMaps,
                                    associatedPath, path, depth, interfaces2);

#ifdef BMCWEB_STATEFUL_CHECK_RESPONSE
    dbus_mapper::getAssociatedSubTreePaths(
        associatedPath, path, depth, interfaces,
        [out2](const boost::system::error_code& ec,
               const MapperGetSubTreePathsResponse& out) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Mapper returned an error " << ec.message();
            return;
        }
        if (out != out2)
        {
            BMCWEB_LOG_CRITICAL
                << "Dbus GetAssociatedSubtreePaths doesn't match mapper lite";
        }
        else
        {
            BMCWEB_LOG_DEBUG
                << "Dbus GetAssociatedSubtreePaths matched mapper lite";
        }
        });
#endif

    boost::system::error_code ec;
    callback(ec, out2);
}
inline void
    getDbusObject(const std::string& path,
                  std::span<const std::string_view> interfaces,
                  std::function<void(const boost::system::error_code&,
                                     const MapperGetObject&)>&& callback)
{
    if (!isMapperLiteEnabled())
    {
        dbus_mapper::getDbusObject(path, interfaces, std::move(callback));
        return;
    }
    BMCWEB_LOG_DEBUG << "Mapper lite getDbusObject called interfaceMap.size()="
                     << interfaceMap.size();
    std::vector<std::string> interfaces2;
    for (auto& s : interfaces)
    {
        interfaces2.emplace_back(s);
    }
    ConnectionNames out = ::getObject(interfaceMap, path, interfaces2);

    MapperGetObject out2;
    for (const auto& connection : out)
    {
        auto& newConnections = out2.emplace_back(std::make_pair(
            connection.first, MapperGetObject::value_type::second_type{}));
        for (const auto& path2 : connection.second)
        {
            newConnections.second.emplace_back(path2);
        }
    }
#ifdef BMCWEB_STATEFUL_CHECK_RESPONSE
    dbus_mapper::getDbusObject(path, interfaces,
                               [out2](const boost::system::error_code& ec,
                                      const MapperGetObject& out) {
        if (ec)
        {
            BMCWEB_LOG_ERROR << "Mapper returned an error " << ec.message();
            return;
        }
        if (out != out2)
        {
            BMCWEB_LOG_CRITICAL << "Dbus GetObject doesn't match mapper lite";
        }
        else
        {
            BMCWEB_LOG_DEBUG << "Dbus GetObject matched mapper lite";
        }
    });
#endif
    boost::system::error_code ec;
    callback(ec, out2);
}

// TODO: Deprecate the API to allow routing through managedStore via API in
// dbus_utils.hpp
template <typename PropertyType>
void getProperty(const std::string& service,
                 const sdbusplus::message::object_path& path,
                 const std::string& interface, const std::string& property,
                 std::function<void(const boost::system::error_code&,
                                    const PropertyType&)>&& callback)
{
    sdbusplus::asio::getProperty<PropertyType>(*crow::connections::systemBus,
                                               service, path.str, interface,
                                               property, std::move(callback));
}

inline void getProperty(const std::string& service,
                        const sdbusplus::message::object_path& path,
                        const std::string& interface,
                        const std::string& property,
                        std::function<void(const boost::system::error_code&,
                                           const DbusVariantType&)>&& callback)
{
    crow::connections::systemBus->async_method_call(
        [callback{std::move(callback)}](const boost::system::error_code& ec,
                                        const DbusVariantType& propertyValue) {
        callback(ec, propertyValue);
        },
        service, path, "org.freedesktop.DBus.Properties", "Get", interface,
        property);
}

inline void getAssociationEndPoints(
    const std::string& path,
    std::function<void(const boost::system::error_code&,
                       const MapperEndPoints&)>&& callback)
{
    getProperty<MapperEndPoints>("xyz.openbmc_project.ObjectMapper", {path},
                                 "xyz.openbmc_project.Association", "endpoints",
                                 std::move(callback));
}

inline void
    getManagedObjects(const std::string& service,
                      const sdbusplus::message::object_path& path,
                      std::function<void(const boost::system::error_code&,
                                         const ManagedObjectType&)>&& callback)
{
    crow::connections::systemBus->async_method_call(
        [callback{std::move(callback)}](const boost::system::error_code& ec,
                                        const ManagedObjectType& objects) {
        callback(ec, objects);
        },
        service, path, "org.freedesktop.DBus.ObjectManager",
        "GetManagedObjects");
}

} // namespace utility
} // namespace dbus
