/*
 * Copyright 2023 Google LLC
 *
 * 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.
 */

#ifndef THIRD_PARTY_ECCLESIA_LIB_REDFISH_EVENT_SERVER_SUBSCRIPTION_H_
#define THIRD_PARTY_ECCLESIA_LIB_REDFISH_EVENT_SERVER_SUBSCRIPTION_H_

#include <cstddef>
#include <cstdint>
#include <functional>
#include <memory>
#include <optional>
#include <string>
#include <unordered_set>
#include <vector>

#include "absl/container/flat_hash_map.h"
#include "absl/container/flat_hash_set.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "absl/types/span.h"
#include "nlohmann/json.hpp"

namespace ecclesia {

// Represents an event source identifier
struct EventSourceId {
  // Enum representing the type of event source
  enum class Type : uint8_t {
    // D-Bus objects as event sources
    kDbusObjects = 0,
    // Socket IO as event sources
    kSocketIO = 1,
    // File IO as event sources
    kFileIO = 2
  };

  EventSourceId(absl::string_view key_in, Type type_in)
      : key(key_in), type(type_in) {}

  template <typename H>
  friend H AbslHashValue(H h, const EventSourceId &n) {
    return H::combine(std::move(h), n.key);
  }

  bool operator==(const EventSourceId &other) const {
    return key == other.key && type == other.type;
  }
  bool operator!=(const EventSourceId &other) const {
    return !(*this == other);
  }

  // Converts EventSourceId to JSON format
  nlohmann::json ToJSON() const;

  // Converts EventSourceId to string format
  std::string ToString() const;

  // Unique identifier for the event source
  std::string key;

  // Type of event source, represented by the Type enum
  Type type;
};

// Uniquely identifies subscription.
struct SubscriptionId {
  explicit SubscriptionId(size_t subscription_id_in)
      : subscription_id(subscription_id_in) {}

  template <typename H>
  friend H AbslHashValue(H h, const SubscriptionId &n) {
    return H::combine(std::move(h), n.subscription_id);
  }

  bool operator==(const SubscriptionId &other) const {
    return subscription_id == other.subscription_id;
  }

  bool operator!=(const SubscriptionId &other) const {
    return !(*this == other);
  }

  size_t Id() const { return subscription_id; }
  size_t subscription_id;
};

// EventId uniquely identifies an event at any given point in time from any
// event source.
//
// EventId satisfies the contract of uniqueness through `redfish_event_id` and
// monotonicity through `timestamp`. `EventId` has an association with
// `SubscriptionId` to allow subscription service to group events for a
// subscriber, useful to satisfy lossless-events contract.
struct EventId {
  EventId(const SubscriptionId &subscription_id_in,
          const EventSourceId &source_id_in, absl::Time timestamp_in);

  // Converts EventId to string format
  std::string ToString() const;

  // Converts EventId to JSON format
  nlohmann::json ToJSON() const;

  template <typename H>
  friend H AbslHashValue(H h, const EventId &n) {
    return H::combine(std::move(h), n.redfish_event_id);
  }

  bool operator==(EventId const& event_id) const {
    return ((event_id.source_id == this->source_id) &&
            (event_id.timestamp == this->timestamp) &&
            (event_id.subscription_id == this->subscription_id) &&
            (event_id.redfish_event_id == this->redfish_event_id));
  }

  bool operator!=(EventId const& event_id) const {
    return !(*this == event_id);
  }

  EventSourceId source_id;
  absl::Time timestamp;
  SubscriptionId subscription_id;
  size_t redfish_event_id;
};

// Structure representing a Trigger, which defines event triggering conditions
struct Trigger {
  using EventSourceToUri =
      absl::flat_hash_map<EventSourceId, std::vector<std::string>>;

  // Static method to create a Trigger object from raw data
  static absl::StatusOr<Trigger> Create(const nlohmann::json &trigger_json);

  // Constructor for Trigger
  explicit Trigger(absl::string_view id_in,
                   absl::flat_hash_set<std::string> origin_resources_in,
                   absl::string_view predicate_in = "", bool mask_in = false);

  // Trigger id
  std::string id;

  // Converts Trigger to JSON format
  nlohmann::json ToJSON() const;

  // Converts Trigger to string format
  std::string ToString() const;

  // List of origin resources associated with the Trigger
  absl::flat_hash_set<std::string> origin_resources;

  // Predicate expression for determining when to trigger the event
  std::string predicate;

  // Flag indicating whether to mask event source.
  bool mask;
};

// Structure representing a subscription
struct SubscriptionContext {
  SubscriptionContext(
      const SubscriptionId &subscription_id_in,
      const absl::flat_hash_map<EventSourceId, absl::flat_hash_set<std::string>>
          &event_source_to_uris_in,
      absl::flat_hash_map<std::string, Trigger> id_to_triggers_in,
      std::function<void(const nlohmann::json &)> &&on_event_callback_in);

  // Unique identifier for the subscription
  SubscriptionId subscription_id;

  // Map of event source IDs to corresponding URIs.
  // This map is used to process incoming events by looking up the URI an event
  // is associated with and then the URI is used to create an internal query
  // that builds `OriginOfCondtion`.
  absl::flat_hash_map<EventSourceId, absl::flat_hash_set<std::string>>
      event_source_to_uri;

  // Map of trigger IDs to corresponding Trigger objects
  // This map associates each trigger ID with the corresponding Trigger
  // object, enabling efficient lookup and management of triggers for a given
  // subscription.
  absl::flat_hash_map<std::string, Trigger> id_to_triggers;

  // Event callback to be invoked for events related to this subscription
  // This callback function is defined for each subscription and will be
  // called whenever an event occurs that matches the criteria defined by the
  // subscription's triggers. The callback function receives the event data as
  // its argument.
  std::function<void(const nlohmann::json &)> on_event_callback;

  // Peer's authenticated Redfish privileges
  std::unordered_set<std::string> privileges;
};

// Interface for an event store.
// EventStore stores events in an overwriting circular buffer and allows
// looking up the events queued since a specific event_id to honor the
// lossless eventing contract of subscription service.
//
// The event store shall be thread safe.
class EventStore {
 public:
  virtual ~EventStore() = default;

  // Adds a new event to the overwriting circular buffer.
  virtual void AddNewEvent(const EventId &event_id,
                           const nlohmann::json &event) = 0;

  // Retrieves all events that have been added since (but not including) the
  // given redfish event id in a chronological order determined by
  // `event_id.timestamp`.
  // If `redfish_event_id` is std::nullopt value, all events shall be returned
  // in chronological order.
  virtual std::vector<nlohmann::json> GetEventsSince(
      std::optional<size_t> redfish_event_id) = 0;

  // Retrieves the event with the given event id.
  virtual nlohmann::json GetEvent(const EventId &event_id) = 0;

  virtual std::vector<nlohmann::json> GetEventsBySubscriptionId(
      size_t subscription_id) = 0;

  // Report all events in the JSON format.
  virtual nlohmann::json ToJSON() = 0;

  // Report all events in the string format.
  virtual std::string ToString() = 0;

  // Cleat all events from the store.
  virtual void Clear() = 0;
};

// Interface for a subscription store
class SubscriptionStore {
 public:
  virtual ~SubscriptionStore() = default;

  // Adds a new subscription with the given subscription ID and event source IDs
  virtual absl::Status AddNewSubscription(
      std::unique_ptr<SubscriptionContext> subscription_context) = 0;

  // Deletes the subscription with the given subscription ID
  virtual void DeleteSubscription(const SubscriptionId &subscription_id) = 0;

  virtual absl::StatusOr<const SubscriptionContext *> GetSubscription(
      const SubscriptionId &subscription_id) = 0;

  // Retrieves the subscriptions associated with the given event source ID
  virtual absl::StatusOr<absl::Span<const ecclesia::SubscriptionContext *const>>
  GetSubscriptionsByEventSourceId(const EventSourceId &source_id) = 0;

  // Converts SubscriptionStore to JSON format
  virtual nlohmann::json ToJSON() = 0;

  // Converts SubscriptionStore to string format
  virtual std::string ToString() = 0;
};

// Interface for a SubscriptionService backend.
// This ensures that SubscriptionService interoperates with different Redfish
// backends by standardizing the interface to subscribe and query Redfish
// resources.
class SubscriptionBackend {
 public:
  // Callback type for Redfish queries.
  using QueryCallback =
      std::function<void(const absl::Status & /*Status Code*/,
                         const nlohmann::json & /*Redfish Resource json_str*/)>;

  // Callback type for Subscribe requests to SubscriptionBackend.
  // This callback shall be invoked with collection of EventSourceId objects on
  // a successful completion or an error in the status code on failed
  // subscription.
  using SubscribeCallback =
      std::function<void(const absl::Status & /*Status Code*/,
                         const std::vector<EventSourceId> & /*EventSources*/)>;

  // Destructor for SubscriptionBackend
  virtual ~SubscriptionBackend() = default;

  // Performs a Redfish query at the given URL and invokes the provided callback
  // with the query result.
  // `peer_privileges` is the peer's Redfish privileges that will be used to
  // authorize the queried resources.
  virtual absl::Status Query(
      absl::string_view url, QueryCallback &&query_callback,
      const std::unordered_set<std::string> &peer_privileges) = 0;

  // Subscribes to Redfish events for the given URL and invokes the callback
  // post subscription.
  // `peer_privileges` is the peer's Redfish privileges that will be used to
  // authorize the subscribed resources.
  virtual absl::Status Subscribe(
      absl::string_view url, SubscribeCallback &&subscribe_callback,
      const std::unordered_set<std::string> &peer_privileges) = 0;
};

// Interface for a subscription service
class SubscriptionService {
 public:
  virtual ~SubscriptionService() = default;

  // Creates a new subscription and returns the subscription ID of the newly
  // created subscription.
  // Note: the implementation must guarantee that `on_event_callback` will only
  // be called once at a time. No parallel call will be allowed!
  virtual void CreateSubscription(
      const nlohmann::json &request,
      const std::unordered_set<std::string> &peer_privileges,
      std::function<void(const absl::StatusOr<SubscriptionId> &)>
          on_subscribe_callback,
      std::function<void(const nlohmann::json &)> on_event_callback) = 0;

  // Deletes the subscription with the given subscription ID
  virtual void DeleteSubscription(const SubscriptionId &subscription_id) = 0;

  // Retrieves all subscriptions managed by the service.
  virtual absl::Span<const SubscriptionContext> GetAllSubscriptions() = 0;

  // Returns all subscriptions in a JSON format.
  virtual nlohmann::json GetSubscriptionsToJSON() = 0;

  // Returns all subscriptions in a string format.
  virtual std::string GetSubscriptionsToString() = 0;

  // Returns all subscriptions in a JSON format.
  virtual nlohmann::json GetEventsToJSON() = 0;

  // Returns all subscriptions in a string format.
  virtual std::string GetEventsToString() = 0;

  // clear/flush all events in the event store.
  virtual void ClearEventStore() = 0;

  virtual nlohmann::json GetEventsBySubscriptionIdToJSON(
      size_t subscriber_id) = 0;

  // Invoked by an EventSource to notify SubscriptionService about an event
  // occurrence.
  // Returns error if notification cannot be processed, typically used to
  // indicate event source that subscription is deleted and the source should
  // disable event listener.
  virtual absl::Status Notify(EventSourceId event_source_id,
                              const absl::Status &status) = 0;

  // Invoked by an EventSource to notify SubscriptionService about an event
  // occurrence along with providing data associated with the event.
  // This method is preferred when the event source is capable of constructing
  // entire OriginOfCondition for event.
  virtual absl::Status NotifyWithData(EventSourceId key, absl::Status status,
                                      const nlohmann::json &data) = 0;
};

}  // namespace ecclesia

#endif  // THIRD_PARTY_ECCLESIA_LIB_REDFISH_EVENT_SERVER_SUBSCRIPTION_H_
