#ifndef THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_HEALTH_H_
#define THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_HEALTH_H_

/*
// Copyright (c) 2019 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 <algorithm>
#include <array>
#include <cstddef>
#include <cstdint>
#include <map>
#include <memory>
#include <optional>
#include <set>
#include <string>
#include <string_view>
#include <variant>
#include <vector>

#include "logging.hpp"
#include "async_resp.hpp"
#include "dbus_utility.hpp"
#include <nlohmann/json.hpp>
#include "managed_store.hpp"
#include "managed_store_types.hpp"

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

namespace redfish {

struct HealthAttributes {
  std::string criteriaId = "";  // ID for health evaluation criteria
  std::string severity = "";
  // Following are used to populate the HealthMonitor log entry
  std::vector<std::string> messageArgs;
  std::string failureMessageId = "";
  std::string okMessageId = "";
  std::string resolution = "";
  std::string oDataId = "";
  std::string logId = "";  // links a log entry
  std::string fruName = "";
  std::string fruType = "";
  std::string boardName = "";
  // Updated from reading HealthMonitor service
  bool health = true;
  uint64_t toggleCount = 0;
  std::string timestamp;
};

// Info needed to create a log entry
struct LogEntry {
  LogEntry(std::string dbus_path, std::string timestamp, std::string severity)
      : dbus_path(dbus_path), timestamp(timestamp), severity(severity) {}
  std::string dbus_path;
  std::string timestamp;
  std::string severity;
};

/**
 * This is a singleton class that caches health status of all redfish resources
 * that are monitored by Health monitor service.
 */
class HealthStatusCache {
  // Maps for fast lookup
  std::map<std::string,                /* Board name */
           std::map<std::string,        /* Entity type */
                    std::map<std::string,        /* Entity name */
                             /* Dbus obj paths of criterias */
                             std::set<std::string>>>>
      entityCache;
  std::map<std::string,  // Health status object path
           HealthAttributes>  // its corresponding HealthAttributes
      healthStatusMap;
  std::vector<LogEntry> logEntries;
  HealthStatusCache();

 public:
  static HealthStatusCache& getInstance() {
    static HealthStatusCache hsc;
    return hsc;
  }
  std::optional<std::string> healthStatusPopulate(
    std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
    const std::string& oDataId,
    const std::string& boardPath,
    const std::string& entityType,
    const std::string& entityName,
    nlohmann::json::json_pointer statusPtr);
  void getHealthAttributes(const std::string& objPath);
  void processHealthStatusChange(const std::string& dbusPath);
  size_t fillLogEntries(nlohmann::json& logEntryArray,
                        const std::string& systemName);
  void fillLogEntry(nlohmann::json::object_t& logEntry, size_t idx,
                    const std::string& systemName);
  void clear() {
    healthStatusMap.clear();
    entityCache.clear();
    logEntries.clear();
  }
};

struct HealthPopulate : std::enable_shared_from_this<HealthPopulate> {
  // By default populate status to "/Status" of |asyncResp->res.jsonValue|.
  explicit HealthPopulate(const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn)
      : asyncResp(asyncRespIn), statusPtr("/Status") {}

  // Takes a JSON pointer rather than a reference. This is pretty useful when
  // the address of the status JSON might change, for example, elements in an
  // array.
  HealthPopulate(const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn,
                 const nlohmann::json::json_pointer& ptr)
      : asyncResp(asyncRespIn), statusPtr(ptr) {}

  HealthPopulate(const HealthPopulate&) = delete;
  HealthPopulate(HealthPopulate&&) = delete;
  HealthPopulate& operator=(const HealthPopulate&) = delete;
  HealthPopulate& operator=(const HealthPopulate&&) = delete;
  HealthPopulate(const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn,
                 const std::string& oDataId, const std::string& boardPath,
                 const std::string& entityType,
                 const std::string& entityName) :
    asyncResp(asyncRespIn), statusPtr("/Status"), oDataId(oDataId),
    boardPath(boardPath), entityType(entityType), entityName(entityName) {}

  ~HealthPopulate() {
    nlohmann::json& jsonStatus = asyncResp->res.jsonValue[statusPtr];
    nlohmann::json& health = jsonStatus["Health"];
    nlohmann::json& rollup = jsonStatus["HealthRollup"];

    health = "OK";
    rollup = "OK";

    for (const std::shared_ptr<HealthPopulate>& healthChild : children) {
      healthChild->globalInventoryPath = globalInventoryPath;
      healthChild->statuses = statuses;
    }

    for (const auto& [path, interfaces] : statuses) {
      bool isSelf = false;
      if (selfPath) {
        if ((*selfPath == path.str) || path.str.starts_with(*selfPath + "/")) {
          isSelf = true;
        }
      }

      // managers inventory is all the inventory, don't skip any
      if (!isManagersHealth && !isSelf) {
        // We only want to look at this association if either the path
        // of this association is an inventory item, or one of the
        // endpoints in this association is a child

        bool isChild = false;
        for (const std::string& child : inventory) {
          if (path.str.starts_with(child)) {
            isChild = true;
            break;
          }
        }
        if (!isChild) {
          for (const auto& [interface, association] : interfaces) {
            if (interface != "xyz.openbmc_project.Association") {
              continue;
            }
            for (const auto& [name, value] : association) {
              if (name != "endpoints") {
                continue;
              }

              const std::vector<std::string>* endpoints =
                  std::get_if<std::vector<std::string>>(&value);
              if (endpoints == nullptr) {
                BMCWEB_LOG_ERROR << "Illegal association at " << path.str;
                continue;
              }
              bool containsChild = false;
              for (const std::string& endpoint : *endpoints) {
                if (std::find(inventory.begin(), inventory.end(), endpoint) !=
                    inventory.end()) {
                  containsChild = true;
                  break;
                }
              }
              if (!containsChild) {
                continue;
              }
            }
          }
        }
      }

      if (path.str.starts_with(globalInventoryPath) &&
          path.str.ends_with("critical")) {
        health = "Critical";
        rollup = "Critical";
        return;
      }
      if (path.str.starts_with(globalInventoryPath) &&
          path.str.ends_with("warning")) {
        health = "Warning";
        if (rollup != "Critical") {
          rollup = "Warning";
        }
      } else if (path.str.ends_with("critical")) {
        rollup = "Critical";
        if (isSelf) {
          health = "Critical";
          return;
        }
      } else if (path.str.ends_with("warning")) {
        if (rollup != "Critical") {
          rollup = "Warning";
        }

        if (isSelf) {
          health = "Warning";
        }
      }
    }

    auto error = HealthStatusCache::getInstance().healthStatusPopulate(
            asyncResp, oDataId, boardPath, entityType, entityName, statusPtr);
    if (error)
    {
        BMCWEB_LOG_ERROR << "Failed to populate health status for boardPath "
                         << boardPath << ". Error: " << *error;
    }

    for (const auto& [path, interfaces] : statuses) {
      bool isSelf = false;
      if (selfPath) {
        if ((*selfPath == path.str) || path.str.starts_with(*selfPath + "/")) {
          isSelf = true;
        }
      }

      // managers inventory is all the inventory, don't skip any
      if (!isManagersHealth && !isSelf) {
        // We only want to look at this association if either the path
        // of this association is an inventory item, or one of the
        // endpoints in this association is a child

        bool isChild = false;
        for (const std::string& child : inventory) {
          if (path.str.starts_with(child)) {
            isChild = true;
            break;
          }
        }
        if (!isChild) {
          for (const auto& [interface, association] : interfaces) {
            if (interface != "xyz.openbmc_project.Association") {
              continue;
            }
            for (const auto& [name, value] : association) {
              if (name != "endpoints") {
                continue;
              }

              const std::vector<std::string>* endpoints =
                  std::get_if<std::vector<std::string>>(&value);
              if (endpoints == nullptr) {
                BMCWEB_LOG_ERROR << "Illegal association at " << path.str;
                continue;
              }
              bool containsChild = false;
              for (const std::string& endpoint : *endpoints) {
                if (std::find(inventory.begin(), inventory.end(), endpoint) !=
                    inventory.end()) {
                  containsChild = true;
                  break;
                }
              }
              if (!containsChild) {
                continue;
              }
            }
          }
        }
      }

      if (path.str.starts_with(globalInventoryPath) &&
          path.str.ends_with("critical")) {
        health = "Critical";
        rollup = "Critical";
        return;
      }
      if (path.str.starts_with(globalInventoryPath) &&
          path.str.ends_with("warning")) {
        health = "Warning";
        if (rollup != "Critical") {
          rollup = "Warning";
        }
      } else if (path.str.ends_with("critical")) {
        rollup = "Critical";
        if (isSelf) {
          health = "Critical";
          return;
        }
      } else if (path.str.ends_with("warning")) {
        if (rollup != "Critical") {
          rollup = "Warning";
        }

        if (isSelf) {
          health = "Warning";
        }
      }
    }
  }

  // this should only be called once per url, others should get updated by
  // being added as children to the 'main' health object for the page
  void populate() {
    if (populated) {
      return;
    }
    populated = true;
    getAllStatusAssociations();
    getGlobalPath();
  }

  void getGlobalPath() {
    constexpr std::array<std::string_view, 1> interfaces = {
        "xyz.openbmc_project.Inventory.Item.Global"};
    std::shared_ptr<HealthPopulate> self = shared_from_this();
    managedStore::ManagedObjectStoreContext requestContext(asyncResp);
    managedStore::GetManagedObjectStore()->getSubTreePaths(
        "/", 0, interfaces, requestContext,
        [self](const boost::system::error_code& ec,
               const dbus::utility::MapperGetSubTreePathsResponse& resp) {
          if (ec || resp.size() != 1) {
            // no global item, or too many
            return;
          }
          self->globalInventoryPath = resp[0];
        });
  }

  void getAllStatusAssociations() {
    std::shared_ptr<HealthPopulate> self = shared_from_this();
    managedStore::ManagedObjectStoreContext context(asyncResp);
    managedStore::GetManagedObjectStore()->getManagedObjectsWithContext(
        "xyz.openbmc_project.ObjectMapper", {"/"}, context,
        [self](const boost::system::error_code& ec,
               const dbus::utility::ManagedObjectType& resp) {
          if (ec) {
            return;
          }
          self->statuses = resp;
          for (auto it = self->statuses.begin(); it != self->statuses.end();) {
            if (it->first.str.ends_with("critical") ||
                it->first.str.ends_with("warning")) {
              it++;
              continue;
            }
            it = self->statuses.erase(it);
          }
        });
  }

  std::shared_ptr<bmcweb::AsyncResp> asyncResp;
  void populateHealthStatus(const std::string& oDataId,
                            const std::string& boardPath,
                            const std::string& entityType,
                            const std::string& entityName);

  // Will populate the health status into |asyncResp_json[statusPtr]|
  nlohmann::json::json_pointer statusPtr;

  // we store pointers to other HealthPopulate items so we can update their
  // members and reduce dbus calls. As we hold a shared_ptr to them, they get
  // destroyed last, and they need not call populate()
  std::vector<std::shared_ptr<HealthPopulate>> children;

  // self is used if health is for an individual items status, as this is the
  // 'lowest most' item, the rollup will equal the health
  std::optional<std::string> selfPath;

  std::vector<std::string> inventory;
  bool isManagersHealth = false;
  dbus::utility::ManagedObjectType statuses;
  std::string globalInventoryPath = "-";  // default to illegal dbus path
  bool populated = false;
  std::string oDataId = "";
  std::string boardPath = "";
  std::string entityType = "";
  std::string entityName = "";
};
}  // namespace redfish

#endif  // THIRD_PARTY_GBMCWEB_REDFISH_CORE_LIB_HEALTH_H_
