// Copyright 2022 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVICES_LIB_COMPAT_COMPAT_H_
#define SRC_DEVICES_LIB_COMPAT_COMPAT_H_

#include <fidl/fuchsia.driver.compat/cpp/wire.h>
#include <fidl/fuchsia.driver.framework/cpp/wire.h>
#include <lib/driver2/devfs_exporter.h>
#include <lib/driver2/logger.h>
#include <lib/driver2/namespace.h>
#include <lib/driver2/start_args.h>
#include <lib/fit/defer.h>
#include <lib/fpromise/promise.h>
#include <lib/service/llcpp/service_handler.h>
#include <lib/sys/component/llcpp/outgoing_directory.h>

#include <unordered_map>
#include <unordered_set>

#include "src/devices/lib/compat/symbols.h"
#include "src/lib/storage/vfs/cpp/pseudo_dir.h"
#include "src/lib/storage/vfs/cpp/synchronous_vfs.h"

namespace compat {

// This represents a protocol that a driver is offering to a child driver.
struct ProtocolOffer {
  // The name of the protocol being offered. The driver is responsible for
  // making sure this protocol has been exported in it's outgoing directory.
  std::string protocol_name;
  // A callback that will be called when this protocol is going out of scope.
  // This is useful if a driver is exposing a protocol to multiple children,
  // and would like to perform cleanup if all children are removed.
  std::shared_ptr<fit::deferred_callback> remove_protocol_callback;
};

// This represents a service that a driver is offering to a child driver.
struct ServiceOffer {
  struct RenamedInstance {
    std::string source_name;
    std::string target_name;
  };
  // The name of the service being offered. The driver is responsible for
  // making sure this service has been exported in its outgoing directory.
  std::string service_name;
  // The list of instance names that the driver wishes to perform while offering
  // the service.
  std::vector<RenamedInstance> renamed_instances;
  // The list of instances the driver wishes to offer with this service.
  // If this is empty, all instances will be included.
  // NOTE: If a rename is happening, this should be the list of new names.
  std::vector<std::string> included_instances;
  // A callback that will be called when this service offer is going out of scope.
  // This is useful if a driver is exposing a service to multiple children,
  // and would like to perform cleanup if all children are removed.
  std::shared_ptr<fit::deferred_callback> remove_service_callback;
};

class ChildOffers {
 public:
  void AddProtocol(ProtocolOffer offer) { protocol_offers_.push_back(std::move(offer)); }

  void AddService(ServiceOffer offer) { service_offers_.push_back(std::move(offer)); }

  std::vector<fuchsia_component_decl::wire::Offer> CreateOffers(fidl::ArenaBase& arena);

 private:
  std::vector<ProtocolOffer> protocol_offers_;
  std::vector<ServiceOffer> service_offers_;
};

using Metadata = std::vector<uint8_t>;
using MetadataMap = std::unordered_map<uint32_t, const Metadata>;

// The DeviceServer class vends the fuchsia_driver_compat::Device interface.
// It represents a single device.
class DeviceServer : public fidl::WireServer<fuchsia_driver_compat::Device> {
 public:
  DeviceServer(std::string topological_path, MetadataMap metadata)
      : topological_path_(std::move(topological_path)), metadata_(std::move(metadata)) {}

  // Functions to implement the DFv1 device API.
  zx_status_t AddMetadata(uint32_t type, const void* data, size_t size);
  zx_status_t GetMetadata(uint32_t type, void* buf, size_t buflen, size_t* actual);
  zx_status_t GetMetadataSize(uint32_t type, size_t* out_size);

  void set_dir(fidl::ClientEnd<fuchsia_io::Directory> dir) { dir_ = std::move(dir); }

 private:
  // fuchsia.driver.compat.Compat
  void GetTopologicalPath(GetTopologicalPathRequestView request,
                          GetTopologicalPathCompleter::Sync& completer) override;
  void GetMetadata(GetMetadataRequestView request, GetMetadataCompleter::Sync& completer) override;
  void ConnectFidl(ConnectFidlRequestView request, ConnectFidlCompleter::Sync& completer) override;

  std::string topological_path_;
  MetadataMap metadata_;
  fidl::ClientEnd<fuchsia_io::Directory> dir_;
};

class Child;

// The Interop class holds information about what this component is exposing in its namespace.
// This class is used to expose things in the outgoing namespace in a way that a child
// compat driver can understand.
class Interop {
 public:
  // Create an Interop. Each parameter here is an unowned pointer, so these objects must outlive
  // the Interop class.
  static zx::status<Interop> Create(async_dispatcher_t* dispatcher, const driver::Namespace* ns,
                                    component::OutgoingDirectory* outgoing);

  // Take a Child, and export its fuchsia.driver.compat service, and it export it to devfs.
  fpromise::promise<void, zx_status_t> ExportChild(Child* child, fbl::RefPtr<fs::Vnode> dev_node);

 private:
  friend class Child;

  async_dispatcher_t* dispatcher_;
  const driver::Namespace* ns_;
  component::OutgoingDirectory* outgoing_;

  std::unique_ptr<fs::SynchronousVfs> vfs_;
  fbl::RefPtr<fs::PseudoDir> devfs_exports_;
  driver::DevfsExporter exporter_;
};

zx::status<fidl::WireSharedClient<fuchsia_driver_compat::Device>> ConnectToParentDevice(
    async_dispatcher_t* dispatcher, const driver::Namespace* ns, std::string_view name = "default");

// The Child class represents a child device.
// When a Child is removed, it will remove the services it added in the
// outgoing directory.
class Child {
 public:
  Child(std::string name, uint32_t proto_id, std::string topological_path, MetadataMap metadata)
      : topological_path_(std::move(topological_path)),
        name_(std::move(name)),
        proto_id_(proto_id),
        compat_device_(topological_path_, std::move(metadata)) {}

  DeviceServer& compat_device() { return compat_device_; }
  std::string_view name() { return name_; }
  std::string_view topological_path() { return topological_path_; }
  uint32_t proto_id() { return proto_id_; }
  ChildOffers& offers() { return offers_; }

  // This is a way to give the child shared ownership over something.
  // When child is removed, there will be one less reference to callback,
  // and callback will be called when all references are removed.
  void AddCallback(std::shared_ptr<fit::deferred_callback> callback) {
    callbacks_.push_back(std::move(callback));
  }

  // Create a vector of offers based on the service instances that have been added to the child.
  std::vector<fuchsia_component_decl::wire::Offer> CreateOffers(fidl::ArenaBase& arena);

 private:
  std::string topological_path_;
  std::string name_;
  uint32_t proto_id_;

  DeviceServer compat_device_;
  ChildOffers offers_;

  // A list of callbacks to potentially call when this class is destructed.
  std::vector<std::shared_ptr<fit::deferred_callback>> callbacks_;
};

}  // namespace compat

#endif  // SRC_DEVICES_LIB_COMPAT_COMPAT_H_
