// Copyright 2020 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_CAMERA_BIN_DEVICE_WATCHER_DEVICE_WATCHER_IMPL_H_
#define SRC_CAMERA_BIN_DEVICE_WATCHER_DEVICE_WATCHER_IMPL_H_

#include <fuchsia/camera2/hal/cpp/fidl.h>
#include <fuchsia/camera3/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/fidl/cpp/binding.h>
#include <lib/fit/function.h>
#include <lib/fpromise/result.h>
#include <lib/sys/cpp/component_context.h>
#include <zircon/status.h>

#include <memory>
#include <queue>
#include <set>
#include <unordered_map>

#include "lib/async/dispatcher.h"
#include "src/camera/bin/device_watcher/device_instance.h"

namespace camera {

constexpr auto kCameraPath = "/dev/class/camera";

constexpr std::string_view kMipiCsiDeviceInstanceCollectionName{"csi_camera_devices"};
constexpr std::string_view kMipiCsiDeviceInstanceNamePrefix{"csi_camera_device_"};
constexpr std::string_view kMipiCsiDeviceInstanceUrl{
    "fuchsia-pkg://fuchsia.com/camera_device#meta/camera_device.cm"};

constexpr std::string_view kUvcDeviceInstanceCollectionName{"usb_camera_devices"};
constexpr std::string_view kUvcDeviceInstanceNamePrefix{"usb_camera_device_"};
constexpr std::string_view kUvcDeviceInstanceUrl{
    "fuchsia-pkg://fuchsia.com/usb_camera_device#meta/usb_camera_device.cm"};

using ClientId = uint64_t;
using TransientDeviceId = uint64_t;
using PersistentDeviceId = uint64_t;

enum CameraType {
  kCameraTypeMipiCsi = 1,
  kCameraTypeUvc = 2,
};

struct UniqueDevice {
  TransientDeviceId id;
  std::unique_ptr<DeviceInstance> instance;
};

using DevicesMap = std::unordered_map<PersistentDeviceId, UniqueDevice>;

class DeviceWatcherImpl {
 public:
  static fpromise::result<std::unique_ptr<DeviceWatcherImpl>, zx_status_t> Create(
      std::unique_ptr<sys::ComponentContext> context, fuchsia::component::RealmHandle realm,
      async_dispatcher_t* dispatcher);

  fpromise::result<CameraType, zx_status_t> GetDeviceInfoAndIdentifyCameraType(
      fuchsia::hardware::camera::DeviceSyncPtr& dev, fuchsia::camera2::DeviceInfo& device_info,
      const std::string& full_path);
  void AddDeviceByPath(const std::string& path);
  void UpdateClients();
  fidl::InterfaceRequestHandler<fuchsia::camera3::DeviceWatcher> GetHandler();

  sys::ComponentContext* context() { return context_.get(); }

  void OnNewRequest(fidl::InterfaceRequest<fuchsia::camera3::DeviceWatcher> request);

 private:
  void ConnectDynamicChild(fidl::InterfaceRequest<fuchsia::camera3::Device> request,
                           const UniqueDevice& unique_device);

  fpromise::result<PersistentDeviceId, zx_status_t> AddMipiCsiDevice(
      fuchsia::hardware::camera::DeviceHandle camera, fuchsia::camera2::DeviceInfo& device_info,
      const std::string& path);

  fpromise::result<PersistentDeviceId, zx_status_t> AddUvcDevice(
      fuchsia::hardware::camera::DeviceHandle camera, fuchsia::camera2::DeviceInfo& device_info,
      const std::string& path);

  // Implements the server endpoint for a single client, and maintains per-client state.
  class Client : public fuchsia::camera3::DeviceWatcher {
   public:
    explicit Client(DeviceWatcherImpl& watcher);
    static fpromise::result<std::unique_ptr<Client>, zx_status_t> Create(
        DeviceWatcherImpl& watcher, ClientId id,
        fidl::InterfaceRequest<fuchsia::camera3::DeviceWatcher> request,
        async_dispatcher_t* dispatcher);
    void UpdateDevices(const DevicesMap& devices);
    explicit operator bool();

   private:
    void CheckDevicesChanged();
    // |fuchsia::camera3::DeviceWatcher|
    void WatchDevices(WatchDevicesCallback callback) override;
    void ConnectToDevice(TransientDeviceId id,
                         fidl::InterfaceRequest<fuchsia::camera3::Device> request) override;

    DeviceWatcherImpl& watcher_;
    ClientId id_;
    fidl::Binding<fuchsia::camera3::DeviceWatcher> binding_;
    WatchDevicesCallback callback_;
    std::set<TransientDeviceId> last_known_ids_;
    std::optional<std::set<TransientDeviceId>> last_sent_ids_;
  };

  async_dispatcher_t* dispatcher_;
  std::unique_ptr<sys::ComponentContext> context_;
  fuchsia::component::RealmPtr realm_;
  TransientDeviceId device_id_next_ = 1;
  DevicesMap devices_;
  ClientId client_id_next_ = 1;
  std::unordered_map<ClientId, std::unique_ptr<Client>> clients_;
  bool initial_update_received_ = false;
  std::queue<fidl::InterfaceRequest<fuchsia::camera3::DeviceWatcher>> requests_;
};

}  // namespace camera

#endif  // SRC_CAMERA_BIN_DEVICE_WATCHER_DEVICE_WATCHER_IMPL_H_
