/*
 * SPDX-FileCopyrightText: Copyright (c) 2023-2024 NVIDIA CORPORATION &
 * AFFILIATES. All rights reserved. SPDX-License-Identifier: Apache-2.0
 *
 * 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 "base.h"

#include "coroutine.hpp"
#include "log.hpp"
#include "types.hpp"

#include <cxxabi.h>   // abi::__cxa_demangle
#include <stdint.h>
#include <sys/mman.h> // for memfd_create
#include <sys/stat.h> // for fstat
#include <systemd/sd-bus.h>
#include <unistd.h>
#include <unistd.h> // for write and lseek

#include <boost/asio.hpp>
#include <nlohmann/json.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/server.hpp>
#include <xyz/openbmc_project/Software/SecurityCommon/common.hpp>

#include <exception>
#include <filesystem>
#include <iostream>
#include <queue>
#include <string>
#include <typeinfo> // typeid().name()
#include <variant>
#include <vector>

struct DBusMapping
{
    std::string objectPath;   //!< D-Bus object path
    std::string interface;    //!< D-Bus interface
    std::string propertyName; //!< D-Bus property name
    std::string propertyType; //!< D-Bus property type
};

using PropertyValue = std::variant<
    bool, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t,
    double, std::string, std::vector<sdbusplus::message::object_path>,
    std::vector<std::string>, std::vector<uint64_t>,
    std::vector<std::tuple<std::string, std::string, std::string>>>;
using DbusProp = std::string;
using DbusChangedProps = std::map<DbusProp, PropertyValue>;
using ObjectPath = std::string;
using ServiceName = std::string;
using MapperServiceMap = std::vector<std::pair<ServiceName, dbus::Interfaces>>;
using GetSubTreeResponse = std::vector<std::pair<ObjectPath, MapperServiceMap>>;
using GetAssociatedObjectsResponse = std::variant<std::vector<ObjectPath>>;
using PropertyValuesCollection =
    std::vector<std::pair<DbusProp, PropertyValue>>;

#define UUID_INT_SIZE 16
#define UUID_LEN 36
#define MAC_ADDRESS_DATA_LEN 6

// Largest safe integer for double precision (2^53 - 1)
const uint64_t MAX_SAFE_INTEGER_IN_DOUBLE = (1ULL << 53) - 1;

namespace utils
{
constexpr bool Tx = true;
constexpr bool Rx = false;

constexpr auto dbusProperties = "org.freedesktop.DBus.Properties";
constexpr auto mapperService = "xyz.openbmc_project.ObjectMapper";
constexpr auto mapperPath = "/xyz/openbmc_project/object_mapper";
constexpr auto mapperInterface = "xyz.openbmc_project.ObjectMapper";

struct Association
{
    std::string forward;
    std::string backward;
    std::string absolutePath;
};
using Associations =
    std::vector<std::tuple<std::string, std::string, std::string>>;

struct Bitfield256 : bitfield256_t
{
    /**
     * @brief Constructor for Bitfield256, clears all the bits
     *
     */
    Bitfield256();
    /**
     * @brief Set the bit at the given bitNumber
     *
     * @param bitNumber Number of the bit to set
     * @return true if the bit was not set before
     */
    bool setBit(const uint8_t& bitNumber);
    /**
     * @brief Check if any bit is set
     *
     * @return true if any bit is set
     */
    bool isAnyBitSet() const;
    /**
     * @brief Get comma separated list of set bits
     *
     * @return Comma separated list of set bits
     */
    std::string getSetBits() const;
    /**
     * @brief Clear all the bits
     *
     */
    void clear();
};

/** @struct CustomFD
 *
 *  RAII wrapper for file descriptor.
 */
struct CustomFD
{
    CustomFD(const CustomFD&) = delete;
    CustomFD& operator=(const CustomFD&) = delete;
    CustomFD(CustomFD&&) = delete;
    CustomFD& operator=(CustomFD&&) = delete;

    CustomFD(int fd) : fd(fd) {}

    ~CustomFD()
    {
        if (fd >= 0)
        {
            close(fd);
        }
    }

    int operator()() const
    {
        return fd;
    }

    operator int() const
    {
        return fd;
    }

  private:
    int fd = -1;
};

/**
 * @brief The interface for DBusHandler
 */
class IDBusHandler
{
  public:
    virtual ~IDBusHandler() = default;

    virtual std::string getService(const char* path,
                                   const char* interface) const = 0;

    virtual MapperServiceMap getServiceMap(
        const char* path,
        const dbus::Interfaces& ifaceList = dbus::Interfaces()) const = 0;

    virtual GetSubTreeResponse
        getSubtree(const std::string& path, int depth,
                   const dbus::Interfaces& ifaceList) const = 0;

    virtual void setDbusProperty(const DBusMapping& dBusMap,
                                 const PropertyValue& value) const = 0;

    virtual PropertyValue
        getDbusPropertyVariant(const char* objPath, const char* dbusProp,
                               const char* dbusInterface) const = 0;

    virtual PropertyValuesCollection
        getDbusProperties(const char* objPath,
                          const char* dbusInterface) const = 0;

    virtual GetAssociatedObjectsResponse
        getAssociatedObjects(const std::string& path,
                             const std::string& association) const = 0;

    /** @brief The template function to get property from the requested dbus
     *         path
     *
     *  @tparam Property - Excepted type of the property on dbus
     *
     *  @param[in] objPath - The Dbus object path
     *  @param[in] dbusProp - The property name to get
     *  @param[in] dbusInterface - The Dbus interface
     *
     *  @return The value of the property
     *
     *  @throw sdbusplus::exception::exception when dbus request fails
     *         std::bad_variant_access when \p Property and property on dbus do
     *         not match
     */
    template <typename Property>
    auto getDbusProperty(const char* objPath, const char* dbusProp,
                         const char* dbusInterface)
    {
        auto VariantValue = getDbusPropertyVariant(objPath, dbusProp,
                                                   dbusInterface);
        return std::get<Property>(VariantValue);
    }
    /** @brief The template function to get optional property from the requested
     * dbus path without throwing sdbusplus::exception::exception on fail
     *
     *  @tparam Property - Excepted type of the property on dbus
     *
     *  @param[in] objPath - The Dbus object path
     *  @param[in] dbusProp - The property name to get
     *  @param[in] dbusInterface - The Dbus interface
     *
     *  @return The value of the property
     *
     *  @throw std::bad_variant_access when \p Property and property on dbus do
     *         not match
     */
    template <typename Property>
    auto tryGetDbusProperty(const char* objPath, const char* dbusProp,
                            const char* dbusInterface,
                            const Property& defValue = Property())
    {
        try
        {
            return getDbusProperty<Property>(objPath, dbusProp, dbusInterface);
        }
        catch (const sdbusplus::exception::exception&)
        {
            return defValue;
        }
    }
};

/**
 *  @class DBusHandler
 *
 *  Wrapper class to handle the D-Bus calls
 *
 *  This class contains the APIs to handle the D-Bus calls
 *  to cater the request from nsm requester.
 *  A class is created to mock the apis in the test cases
 */
class DBusHandler : public IDBusHandler
{
  public:
    /** @brief Get the bus connection. */
    static auto& getBus()
    {
        static auto bus = sdbusplus::bus::new_default();
        return bus;
    }

    /** @brief Get the asio connection. */
    static auto& getAsioConnection()
    {
        static boost::asio::io_context io;
        static auto conn = std::make_shared<sdbusplus::asio::connection>(io);
        return conn;
    }

    /** @brief Get the DBusHandler instance. */
    static DBusHandler& instance()
    {
        static DBusHandler dBusHandler;
        return dBusHandler;
    }

    /**
     *  @brief Get the DBUS Service name for the input dbus path
     *
     *  @param[in] path - DBUS object path
     *  @param[in] interface - DBUS Interface
     *
     *  @return std::string - the dbus service name
     *
     *  @throw sdbusplus::exception::exception when it fails
     */
    std::string getService(const char* path,
                           const char* interface) const override;

    /**
     *  @brief Get the DBUS ServiceMap for the input dbus path
     *
     *  @param[in] path - DBUS object path
     *  @param[in] ifaceList - list of the interface that are being
     *                         queried from the mapper
     *
     *  @return MapperServiceMap - the dbus services map
     *
     *  @throw sdbusplus::exception::exception when it fails
     */
    MapperServiceMap
        getServiceMap(const char* path,
                      const dbus::Interfaces& ifaceList) const override;

    /**
     *  @brief Get the Subtree response from the mapper
     *
     *  @param[in] path - DBUS object path
     *  @param[in] depth - Search depth
     *  @param[in] ifaceList - list of the interface that are being
     *                         queried from the mapper
     *
     *  @return GetSubTreeResponse - the mapper subtree response
     *
     *  @throw sdbusplus::exception::exception when it fails
     */
    GetSubTreeResponse
        getSubtree(const std::string& path, int depth,
                   const dbus::Interfaces& ifaceList) const override;

    /** @brief Get property(type: variant) from the requested dbus
     *
     *  @param[in] objPath - The Dbus object path
     *  @param[in] dbusProp - The property name to get
     *  @param[in] dbusInterface - The Dbus interface
     *
     *  @return The value of the property(type: variant)
     *
     *  @throw sdbusplus::exception::exception when it fails
     */
    PropertyValue
        getDbusPropertyVariant(const char* objPath, const char* dbusProp,
                               const char* dbusInterface) const override;

    /** @brief Set Dbus property
     *
     *  @param[in] dBusMap - Object path, property name, interface and property
     *                       type for the D-Bus object
     *  @param[in] value - The value to be set
     *
     *  @throw sdbusplus::exception::exception when it fails
     */
    void setDbusProperty(const DBusMapping& dBusMap,
                         const PropertyValue& value) const override;

    /** @brief Get properties(type: variant) from the requested dbus
     *
     *  @param[in] objPath - The Dbus object path
     *  @param[in] dbusInterface - The Dbus interface
     *
     *  @return The collection of the properties (type: variant)
     *
     *  @throw sdbusplus::exception::exception when it fails
     */
    PropertyValuesCollection
        getDbusProperties(const char* objPath,
                          const char* dbusInterface) const override;

    /**
     *  @brief Get the associated object response from the mapper
     *
     *  @param[in] path - DBUS object path
     *  @param[in] association - forward / reverse association
     *
     *  @return GetAssociatedObjectsResponse - the mapper get associated object
     * response
     *
     *  @throw sdbusplus::exception::exception when it fails
     */
    GetAssociatedObjectsResponse
        getAssociatedObjects(const std::string& path,
                             const std::string& association) const override;
};

/** @brief check if the string is met UTF-8 or not based on the dbus spec.
 *
 *  @param[in] input - The input string to be checked
 *  @return - boolean
 */
bool isValidDbusString(std::string_view input);

IDBusHandler& DBusHandler();

/** @brief Print the buffer
 *
 *  @param[in] isTx - True if the buffer is an outgoing NSM message, false if
                      the buffer is an incoming NSM message
 *  @param[in] buffer - Buffer to print
 *  @param[in] tag - Tag to identify the message
 *  @param[in] eid - EID of the message
 *
 *  @return - None
 */
void printBuffer(bool isTx, const std::vector<uint8_t>& buffer, uint8_t tag,
                 eid_t eid);

/** @brief Print the buffer
 *
 *  @param[in] isTx - True if the buffer is an outgoing NSM message, false if
                      the buffer is an incoming NSM message
 *  @param[in] buffer - NSM message buffer to log
 *  @param[in] bufferLen - NSM message buffer length
 *  @param[in] tag - Tag to identify the message
 *  @param[in] eid - EID of the message
 *
 *  @return - None
 */
void printBuffer(bool isTx, const uint8_t* buffer, size_t bufferLen,
                 uint8_t tag, eid_t eid);

/** @brief Split strings according to special identifiers
 *
 *  We can split the string according to the custom identifier(';', ',', '&' or
 *  others) and store it to vector.
 *
 *  @param[in] srcStr       - The string to be split
 *  @param[in] delim        - The custom identifier
 *  @param[in] trimStr      - The first and last string to be trimmed
 *
 *  @return std::vector<std::string> Vectors are used to store strings
 */
std::vector<std::string> split(std::string_view srcStr, std::string_view delim,
                               std::string_view trimStr = "");
/** @brief Get the current system time in readable format
 *
 *  @return - std::string equivalent of the system time
 */
std::string getCurrentSystemTime();

/** @brief Get UUID from the eid
 *
 *  @return - uuid_t uuid for corresponding eid
 */
std::optional<std::string> getUUIDFromEID(
    const std::multimap<std::string,
                        std::tuple<eid_t, MctpMedium, MctpBinding>>& eidTable,
    eid_t eid);

/** @brief Get eid from the UUID
 *
 *  @return - eid_t eid for corresponding UUID
 */
eid_t getEidFromUUID(
    const std::multimap<uuid_t, std::tuple<eid_t, MctpMedium, MctpBinding>>&
        eidTable,
    uuid_t uuid);

/** @brief UUID conversion from integer array to std::string.
 *
 *  @param[in] uuidIntArr   - The integer array to be converted to string
 *  @return - uuid_t
 */
uuid_t convertUUIDToString(const std::vector<uint8_t>& uuidIntArr);

/** @brief string conversion from integer array to std::string.
 *
 *  @param[in] data - The integer array to be converted to string
 *  @param[in] dataSize - The size of the string
 *  @return - std::string
 */
std::string convertHexToString(const std::vector<uint8_t>& data,
                               const size_t dataSize);

/** @brief Make valid D-Bus Object Path of Interface Name by replacing unwanted
 * characters with underscore ('_')
 *
 *  @param[in] name - potentially invalid D-Bus Name
 *  @return - valid D-Bus Name
 */
std::string makeDBusNameValid(const std::string& name);

/** @brief Get associations of a configuration PDI
 *
 *  @param[in] objPath - D-Bus Object Path of configuration PDI
 *  @param[in] interfaceSubStr - Sub string to identify association interfaces
 * at objPath
 *  @return - Associations
 */
std::vector<Association> getAssociations(const std::string& objPath,
                                         const std::string& interfaceSubStr);

/**
 * @brief Converts vector of Association struct to dbus tuples collection
 *
 * @param associations vector of Association struct
 * @return Associations Dbus tuples collection
 */
Associations getAssociations(const std::vector<Association>& associations);

/** @brief Parse bitfield response for nsm command
 *
 * @param[in] data - std::vector<uint8_t>
 * @param[in] const bitfield8_t* value - pointer to bitfield data
 * @param[in] size - uint_8 varuable to hold bitfield data
 */
void convertBitMaskToVector(std::vector<uint8_t>& data,
                            const bitfield8_t* value, uint8_t size);

/**
 * @brief Get Device Name associated to Device Type
 *
 * @param deviceType NSM device type number
 */
std::string getDeviceNameFromDeviceType(const uint8_t deviceType);

/**
 * @brief Get Device Instance Name = deviceName_deviceInstanceNumber
 *
 * @param deviceType NSM device type number
 * @param instanceNumber NSM device instance number
 */
std::string getDeviceInstanceName(const uint8_t deviceType,
                                  const uint8_t instanceNumber);

/** @brief Get associations of a configuration PDI by coroutine
 *
 *  @param[in] objPath - D-Bus Object Path of configuration PDI
 *  @param[in] interfaceSubStr - Sub string to identify association interfaces
 * at objPath
 *  @param[out] - associations
 */

requester::Coroutine coGetAssociations(const std::string& objPath,
                                       const std::string& interfaceSubStr,
                                       std::vector<Association>& associations);

// Function to convert bitfield256_t to a bitmap
/**
 * Converts a bitfield256_t structure to a bitmap.
 *
 * @param bf Pointer to the bitfield256_t structure.
 **/
std::vector<uint8_t> bitfield256_tToBitMap(bitfield256_t bf);

/**
 * @brief Converts a bitmap into two vectors containing the indices of bits set
 * to 0 and 1.
 *
 * @param[in] bitmap - A vector of bytes representing the bitmap.
 * @return A pair of vectors, where the first vector contains the indices of
 * bits that are 0, and the second vector contains the indices of bits that
 * are 1.
 *
 * @note The indices are 0-based, meaning the first bit in the bitmap is index
 * 0.
 */
std::pair<std::vector<uint8_t>, std::vector<uint8_t>>
    bitmapToIndices(const std::vector<uint8_t>& bitmap);

/**
 * @brief Converts a list of indices into a bitmap.
 *
 * @param[in] indices - A vector of 1-based indices where bits should be set
 * to 1.
 * @param[in] size - (optional) size of the output bitmap.
 * @return A vector of bytes representing the bitmap.
 *
 * @note Indices that are not provided in the list will be set to 0 in the
 * bitmap.
 */
std::vector<uint8_t> indicesToBitmap(const std::vector<uint8_t>& indices,
                                     const size_t size = 0);

std::vector<uint8_t> bitfield256_tToBitArray(bitfield256_t bf);

/**
 * @brief Converts a bitfield representing update methods into a list of
 * update method enums.
 *
 * @param[in] updateMethodBitfield - A bitfield where each bit represents a
 * different update method.
 * @return A vector of SecurityCommon::UpdateMethods enums corresponding to
 * the set bits in the bitfield.
 *
 * @note The function checks specific bits in the bitfield and adds the
 * corresponding update method enum to the returned vector. Only the bits
 * that are set in the bitfield will have their corresponding enums included
 * in the list.
 */
std::vector<sdbusplus::common::xyz::openbmc_project::software::SecurityCommon::
                UpdateMethods>
    updateMethodsBitfieldToList(bitfield32_t updateMethodBitfield);

// Function to convert bitmap to a bitfield256_t
/**
 * Converts a bitmap structure to a bitfield256_t.
 *
 * @param bitmap Pointer to the bitmap structure.
 **/
bitfield256_t bitMapToBitfield256_t(const std::vector<uint8_t>& bitmap);

std::string vectorTo256BitHexString(const std::vector<uint8_t>& value);

/**
 * @brief Reads the contents of a file descriptor into a buffer.
 *
 * @param fd File descriptor to read from.
 * @param buffer Buffer to store the read data.
 */
void readFdToBuffer(int fd, std::vector<uint8_t>& buffer);

/**
 * @brief Writes the contents of a buffer to a file descriptor.
 *
 * @param fd File descriptor to write to.
 * @param buffer Buffer to write.
 */
void writeBufferToFd(int fd, const std::vector<uint8_t>& buffer);
/**
 * @brief Writes the contents of a buffer to a file descriptor.
 *
 * @param fd File descriptor to write to.
 * @param buffer Buffer to write.
 */
void appendBufferToFd(int fd, const std::vector<uint8_t>& buffer);

std::string requestMsgToHexString(std::vector<uint8_t>& requestMsg);

/**
 * @brief Writes the contents of a buffer to a file descriptor.
 *
 * @param uint32_t value to be scaled down
 * @param scaleFactor  scaleDown factor.
 * Eg : value = 200000, will be returned as 200 if scaleFactor = 1000
 */
double convertAndScaleDownUint32ToDouble(uint32_t value, double scaleFactor);

/**
 * @brief Convert uint64 to double with safe check.
 *
 * @param uint64_t value to be converted to double
 */
double uint64ToDoubleSafeConvert(uint64_t value);

/**
 * @brief Convert int64 to double with safe check.
 *
 * @param uint64_t value to be converted to double
 */
double int64ToDoubleSafeConvert(int64_t value);

/**
 * @brief Gets type from templated type
 *
 * @tparam T Type to get name of
 * @return std::string Name of the type
 */
template <typename T>
std::string typeName()
{
    auto mangled = typeid(T).name();
    int status = 0;
    auto demangled = abi::__cxa_demangle(mangled, nullptr, nullptr, &status);
    std::string type = (status == 0 && demangled) ? demangled : mangled;
    // Free memory allocated by abi::__cxa_demangle
    std::free(demangled);
    return type;
}

template <typename T>
std::optional<T>
    getPropertyFromCollection(const PropertyValuesCollection& collection,
                              const std::string& name)
{
    auto fit = std::lower_bound(collection.cbegin(), collection.cend(), name,
                                [&](const auto& elem, const std::string& name) {
        return elem.first < name;
    });

    if (fit == collection.cend() || fit->first != name)
    {
        lg2::error("getPropertyFromCollection : Property {PROP} not found.",
                   "PROP", name);

        return std::nullopt;
    }

    return std::get<T>(fit->second);
}

/**
 * @brief Combines device type and role into a single identifier
 * High byte (bits 15-8): Device Role
 * Low byte (bits 7-0): Device Type
 *
 * @param deviceType The NSM device type (NsmDeviceIdentification)
 * @param deviceRole The role specific to the device type
 * @return uint16_t Combined device type and role
 */
uint16_t combineDeviceTypeAndRole(uint8_t deviceType, uint8_t deviceRole);

/**
 * @brief Extracts device type and role from combined identifier
 * High byte (bits 15-8): Device Role
 * Low byte (bits 7-0): Device Type
 *
 * @param combined The combined device type and role value
 * @param deviceType Pointer to store the extracted device type (low byte)
 * @param deviceRole Pointer to store the extracted device role (high byte)
 */
void getDeviceTypeAndRole(uint16_t combined, uint8_t* deviceType,
                          uint8_t* deviceRole);

/**
 * @brief Converts a MAC address to a string representation.
 *
 * @param macAddress Pointer to the MAC address to convert.
 * @param macAddressDataLen Length of the MAC address.
 * @param macAddressString Reference to the string to store the converted MAC
 * address.
 */
void convertMacAddressToString(const uint8_t* macAddress,
                               size_t macAddressDataLen,
                               std::string& macAddressString);

/**
 * @brief Converts a 64-bit GUID to a string representation.
 *
 * @param guid The 64-bit GUID to convert.
 * @param guidString Reference to the string to store the converted GUID.
 */
void convertGuid64ToString(uint64_t guid, std::string& guidString);
} // namespace utils
