#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_NETWORK_PROTOCOL_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_NETWORK_PROTOCOL_H_

/*
// 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.
*/

#include <array>
#include <cstddef>
#include <functional>
#include <memory>
#include <optional>
#include <span>  // NOLINT
#include <string>
#include <string_view>
#include <tuple>
#include <utility>
#include <variant>
#include <vector>

#include "boost/algorithm/string/predicate.hpp"  // NOLINT
#include "boost/system/error_code.hpp"  // NOLINT
#include "app.hpp"
#include "http_request.hpp"
#include "logging.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include "error_messages.hpp"
#include "privileges.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "dbus_utils.hpp"
#include "json_utils.hpp"
#include "stl_utils.hpp"
#include "redfish_util.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"
#include "sdbusplus/message/native_types.hpp"

#ifdef UNIT_TEST_BUILD
#include "test/g3/mock_managed_store.hpp"  // NOLINT
#endif

namespace redfish {

void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp);
std::string getHostName();

static constexpr std::string_view sshServiceName = "dropbear";
static constexpr std::string_view httpsServiceName = "bmcweb";
static constexpr std::string_view ipmiServiceName = "phosphor-ipmi-net";

// Mapping from Redfish NetworkProtocol key name to backend service that hosts
// that protocol.
static constexpr std::array<std::pair<std::string_view, std::string_view>, 3>
    networkProtocolToDbus = {{{"SSH", sshServiceName},
                              {"HTTPS", httpsServiceName},
                              {"IPMI", ipmiServiceName}}};

inline void extractNTPServersAndDomainNamesData(
    const dbus::utility::ManagedObjectType& dbusData,
    std::vector<std::string>& ntpData, std::vector<std::string>& dnData) {
  for (const auto& obj : dbusData) {
    for (const auto& ifacePair : obj.second) {
      if (ifacePair.first != "xyz.openbmc_project.Network.EthernetInterface") {
        continue;
      }

      for (const auto& propertyPair : ifacePair.second) {
        if (propertyPair.first == "StaticNTPServers") {
          const std::vector<std::string>* ntpServers =
              std::get_if<std::vector<std::string>>(&propertyPair.second);
          if (ntpServers != nullptr) {
            ntpData.insert(ntpData.end(), ntpServers->begin(),
                           ntpServers->end());
          }
        } else if (propertyPair.first == "DomainName") {
          const std::vector<std::string>* domainNames =
              std::get_if<std::vector<std::string>>(&propertyPair.second);
          if (domainNames != nullptr) {
            dnData.insert(dnData.end(), domainNames->begin(),
                          domainNames->end());
          }
        }
      }
    }
  }
  stl_utils::removeDuplicate(ntpData);
  stl_utils::removeDuplicate(dnData);
}

template <typename CallbackFunc>
void getEthernetIfaceData(
    const managedStore::ManagedObjectStoreContext& context,
    CallbackFunc&& callback) {
  managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
      "xyz.openbmc_project.Network", {"/xyz/openbmc_project/network"}, context,
      [callback{std::forward<CallbackFunc>(callback)}](
          const boost::system::error_code& errorCode,
          const dbus::utility::ManagedObjectType& dbusData) {
        std::vector<std::string> ntpServers;
        std::vector<std::string> domainNames;

        if (errorCode) {
          callback(false, ntpServers, domainNames);
          return;
        }

        extractNTPServersAndDomainNamesData(dbusData, ntpServers, domainNames);

        callback(true, ntpServers, domainNames);
      });
}

inline void afterNetworkPortRequest(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const boost::system::error_code& ec,
    const std::vector<std::tuple<std::string, std::string, bool>>& socketData) {
  if (ec) {
    messages::internalError(asyncResp->res);
    return;
  }

  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  for (const auto& data : socketData) {
    const std::string& socketPath = get<0>(data);
    const std::string& protocolName = get<1>(data);
    bool isProtocolEnabled = get<2>(data);

    asyncResp->res.jsonValue[protocolName]["ProtocolEnabled"] =
        isProtocolEnabled;
    asyncResp->res.jsonValue[protocolName]["Port"] = nullptr;
    getPortNumber(socketPath, requestContext,
                  [asyncResp, protocolName](
                      const boost::system::error_code& ec2, int portNumber) {
                    if (ec2) {
                      messages::internalError(asyncResp->res);
                      return;
                    }
                    asyncResp->res.jsonValue[protocolName]["Port"] = portNumber;
                  });
  }
}

inline void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                           const crow::Request& req) {
  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/ManagerNetworkProtocol/"
                           "NetworkProtocol.json>; rel=describedby");
  asyncResp->res.jsonValue["@odata.type"] =
      "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol";
  asyncResp->res.jsonValue["@odata.id"] =
      "/redfish/v1/Managers/bmc/NetworkProtocol";
  asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
  asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
  asyncResp->res.jsonValue["Description"] = "Manager Network Service";
  asyncResp->res.jsonValue["Status"]["Health"] = "OK";
  asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
  asyncResp->res.jsonValue["Status"]["State"] = "Enabled";

  // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0,
  // but from security perspective it is not recommended to use.
  // Hence using protocolEnabled as false to make it OCP and security-wise
  // compliant
  asyncResp->res.jsonValue["HTTP"]["Port"] = nullptr;
  asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false;

  std::string hostName = getHostName();

  asyncResp->res.jsonValue["HostName"] = hostName;

  getNTPProtocolEnabled(asyncResp);

  managedStore::ManagedObjectStoreContext context(asyncResp);
  getEthernetIfaceData(
      context,
      [hostName, asyncResp](const bool& success,
                            const std::vector<std::string>& ntpServers,
                            const std::vector<std::string>& domainNames) {
        if (!success) {
          messages::resourceNotFound(asyncResp->res, "ManagerNetworkProtocol",
                                     "NetworkProtocol");
          return;
        }
        asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers;
        if (!hostName.empty()) {
          std::string fqdn = hostName;
          if (!domainNames.empty()) {
            fqdn += ".";
            fqdn += domainNames[0];
          }
          asyncResp->res.jsonValue["FQDN"] = std::move(fqdn);
        }
      });

  Privileges effectiveUserPrivileges = redfish::getUserPrivileges(req.userRole);

  // /redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates is
  // something only ConfigureManager can access then only display when
  // the user has permissions ConfigureManager
  if (isOperationAllowedWithPrivileges({{"ConfigureManager"}},
                                       effectiveUserPrivileges)) {
    asyncResp->res.jsonValue["HTTPS"]["Certificates"]["@odata.id"] =
        "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates";
  }

  getPortStatusAndPath(std::span(networkProtocolToDbus), context,
                       std::bind_front(afterNetworkPortRequest, asyncResp));
}  // namespace redfish

inline void handleNTPProtocolEnabled(
    const bool& ntpEnabled,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  std::string timeSyncMethod;
  if (ntpEnabled) {
    timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.NTP";
  } else {
    timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.Manual";
  }

  managedStore::GetManagedObjectStore()->PostDbusCallToIoContextThreadSafe(
      asyncResp->strand_,
      [asyncResp](const boost::system::error_code& errorCode) {
        if (errorCode) {
          messages::internalError(asyncResp->res);
        }
      },
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
      "org.freedesktop.DBus.Properties", "Set",
      "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod",
      dbus::utility::DbusVariantType{timeSyncMethod});
}

inline void handleNTPServersPatch(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::vector<nlohmann::json>& ntpServerObjects,
    std::vector<std::string> currentNtpServers) {
  std::vector<std::string>::iterator currentNtpServer =
      currentNtpServers.begin();
  for (size_t index = 0; index < ntpServerObjects.size(); index++) {
    const nlohmann::json& ntpServer = ntpServerObjects[index];
    if (ntpServer.is_null()) {
      // Can't delete an item that doesn't exist
      if (currentNtpServer == currentNtpServers.end()) {
        messages::propertyValueNotInList(
            asyncResp->res, "null", "NTP/NTPServers/" + std::to_string(index));

        return;
      }
      currentNtpServer = currentNtpServers.erase(currentNtpServer);
      continue;
    }
    const nlohmann::json::object_t* ntpServerObject =
        ntpServer.get_ptr<const nlohmann::json::object_t*>();
    if (ntpServerObject != nullptr) {
      if (!ntpServerObject->empty()) {
        messages::propertyValueNotInList(
            asyncResp->res,
            ntpServer.dump(2, ' ', true,
                           nlohmann::json::error_handler_t::replace),
            "NTP/NTPServers/" + std::to_string(index));
        return;
      }
      // Can't retain an item that doesn't exist
      if (currentNtpServer == currentNtpServers.end()) {
        messages::propertyValueOutOfRange(
            asyncResp->res,
            ntpServer.dump(2, ' ', true,
                           nlohmann::json::error_handler_t::replace),
            "NTP/NTPServers/" + std::to_string(index));

        return;
      }
      // empty objects should leave the NtpServer unmodified
      currentNtpServer++;
      continue;
    }

    const std::string* ntpServerStr = ntpServer.get_ptr<const std::string*>();
    if (ntpServerStr == nullptr) {
      messages::propertyValueTypeError(
          asyncResp->res,
          ntpServer.dump(2, ' ', true,
                         nlohmann::json::error_handler_t::replace),
          "NTP/NTPServers/" + std::to_string(index));
      return;
    }
    if (currentNtpServer == currentNtpServers.end()) {
      // if we're at the end of the list, append to the end
      currentNtpServers.push_back(*ntpServerStr);
      currentNtpServer = currentNtpServers.end();
      continue;
    }
    *currentNtpServer = *ntpServerStr;
    currentNtpServer++;
  }

  // Any remaining array elements should be removed
  currentNtpServers.erase(currentNtpServer, currentNtpServers.end());

  constexpr std::array<std::string_view, 1> ethInterfaces = {
      "xyz.openbmc_project.Network.EthernetInterface"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project", 0, ethInterfaces, requestContext,
      [asyncResp, currentNtpServers](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", " << ec.message();
          messages::internalError(asyncResp->res);
          return;
        }

        for (const auto& [objectPath, serviceMap] : subtree) {
          for (const auto& [service, interfaces] : serviceMap) {
            for (const auto& interface : interfaces) {
              if (interface !=
                  "xyz.openbmc_project.Network.EthernetInterface") {
                continue;
              }

              managedStore::GetManagedObjectStore()
                  ->PostDbusCallToIoContextThreadSafe(
                      asyncResp->strand_,
                      [asyncResp](const boost::system::error_code& ec2) {
                        if (ec2) {
                          messages::internalError(asyncResp->res);
                          return;
                        }
                      },
                      service, objectPath, "org.freedesktop.DBus.Properties",
                      "Set", interface, "StaticNTPServers",
                      dbus::utility::DbusVariantType{currentNtpServers});
            }
          }
        }
      });
}

inline void handleProtocolEnabled(
    const bool protocolEnabled,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& netBasePath) {
  constexpr std::array<std::string_view, 1> interfaces = {
      "xyz.openbmc_project.Control.Service.Attributes"};
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  managedStore::GetManagedObjectStore()->getSubTree(
      "/xyz/openbmc_project/control/service", 0, interfaces, requestContext,
      [protocolEnabled, asyncResp, netBasePath](
          const boost::system::error_code& ec,
          const dbus::utility::MapperGetSubTreeResponse& subtree) {
        if (ec) {
          messages::internalError(asyncResp->res);
          return;
        }

        for (const auto& entry : subtree) {
          if (boost::algorithm::starts_with(entry.first, netBasePath)) {
            managedStore::GetManagedObjectStore()
                ->PostDbusCallToIoContextThreadSafe(
                    asyncResp->strand_,
                    [asyncResp](const boost::system::error_code& ec2) {
                      if (ec2) {
                        messages::internalError(asyncResp->res);
                        return;
                      }
                    },
                    entry.second.begin()->first, entry.first,
                    "org.freedesktop.DBus.Properties", "Set",
                    "xyz.openbmc_project.Control.Service.Attributes", "Running",
                    dbus::utility::DbusVariantType{protocolEnabled});

            managedStore::GetManagedObjectStore()
                ->PostDbusCallToIoContextThreadSafe(
                    asyncResp->strand_,
                    [asyncResp](const boost::system::error_code& ec2) {
                      if (ec2) {
                        messages::internalError(asyncResp->res);
                        return;
                      }
                    },
                    entry.second.begin()->first, entry.first,
                    "org.freedesktop.DBus.Properties", "Set",
                    "xyz.openbmc_project.Control.Service.Attributes", "Enabled",
                    dbus::utility::DbusVariantType{protocolEnabled});
          }
        }
      });
}

inline std::string getHostName() {
  std::string hostName;

  std::array<char, HOST_NAME_MAX> hostNameCStr{};
  if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) {
    hostName = hostNameCStr.data();
  }
  return hostName;
}

inline void getNTPProtocolEnabled(
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  managedStore::ManagedObjectStoreContext requestContext(asyncResp);
  dbus_utils::getProperty<std::string>(
      "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method",
      "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod",
      requestContext,
      [asyncResp](const boost::system::error_code& errorCode,
                  const std::string& timeSyncMethod) {
        if (errorCode) {
          return;
        }

        if (timeSyncMethod ==
            "xyz.openbmc_project.Time.Synchronization.Method.NTP") {
          asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true;
        } else if (timeSyncMethod ==
                   "xyz.openbmc_project.Time.Synchronization."
                   "Method.Manual") {
          asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false;
        }
      });
}

inline std::string encodeServiceObjectPath(std::string_view serviceName) {
  sdbusplus::message::object_path objPath(
      "/xyz/openbmc_project/control/service");
  objPath /= serviceName;
  return objPath.str;
}

inline void handleBmcNetworkProtocolHead(
    crow::App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/ManagerNetworkProtocol/"
                           "ManagerNetworkProtocol.json>; rel=describedby");
}

inline void handleManagersNetworkProtocolPatch(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  std::optional<std::string> newHostName;
  std::optional<std::vector<nlohmann::json>> ntpServerObjects;
  std::optional<bool> ntpEnabled;
  std::optional<bool> ipmiEnabled;
  std::optional<bool> sshEnabled;

  // clang-format off
        if (!json_util::readJsonPatch(
                req, asyncResp->res,
                "HostName", newHostName,
                "NTP/NTPServers", ntpServerObjects,
                "NTP/ProtocolEnabled", ntpEnabled,
                "IPMI/ProtocolEnabled", ipmiEnabled,
                "SSH/ProtocolEnabled", sshEnabled))
        {
            return;
        }
  // clang-format on

  asyncResp->res.result(boost::beast::http::status::no_content);
  if (newHostName) {
    messages::propertyNotWritable(asyncResp->res, "HostName");
    return;
  }

  if (ntpEnabled) {
    handleNTPProtocolEnabled(*ntpEnabled, asyncResp);
  }
  if (ntpServerObjects) {
    managedStore::ManagedObjectStoreContext context(asyncResp);
    getEthernetIfaceData(
        context,
        [asyncResp, ntpServerObjects](
            const bool success, std::vector<std::string>& currentNtpServers,
            const std::vector<std::string>& /*domainNames*/) {
          if (!success) {
            messages::internalError(asyncResp->res);
            return;
          }
          handleNTPServersPatch(asyncResp, *ntpServerObjects,
                                std::move(currentNtpServers));
        });
  }

  if (ipmiEnabled) {
    handleProtocolEnabled(
        *ipmiEnabled, asyncResp,
        encodeServiceObjectPath(std::string(ipmiServiceName) + '@'));
  }

  if (sshEnabled) {
    handleProtocolEnabled(*sshEnabled, asyncResp,
                          encodeServiceObjectPath(sshServiceName));
  }
}

inline void handleManagersNetworkProtocolHead(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  if (!redfish::setUpRedfishRoute(app, req, asyncResp)) {
    return;
  }
  asyncResp->res.addHeader(boost::beast::http::field::link,
                           "</redfish/v1/JsonSchemas/ManagerNetworkProtocol/"
                           "ManagerNetworkProtocol.json>; rel=describedby");
}

inline void handleManagersNetworkProtocolGet(
    App& app, const crow::Request& req,
    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
  handleManagersNetworkProtocolHead(app, req, asyncResp);
  getNetworkData(asyncResp, req);
}

inline void requestRoutesNetworkProtocol(App& app) {
  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
      .privileges(redfish::privileges::patchManagerNetworkProtocol)
      .methods(boost::beast::http::verb::patch)(
          std::bind_front(handleManagersNetworkProtocolPatch, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
      .privileges(redfish::privileges::headManagerNetworkProtocol)
      .methods(boost::beast::http::verb::head)(
          std::bind_front(handleManagersNetworkProtocolHead, std::ref(app)));

  BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
      .privileges(redfish::privileges::getManagerNetworkProtocol)
      .methods(boost::beast::http::verb::get)(
          std::bind_front(handleManagersNetworkProtocolGet, std::ref(app)));
}

}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_NETWORK_PROTOCOL_H_
