/*
 * Copyright 2021 The Chromium OS 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 CAMERA_COMMON_SENSOR_HAL_CLIENT_IMPL_H_
#define CAMERA_COMMON_SENSOR_HAL_CLIENT_IMPL_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include <base/memory/weak_ptr.h>
#include <base/single_thread_task_runner.h>
#include <base/synchronization/lock.h>
#include <iioservice/mojo/cros_sensor_service.mojom.h>
#include <iioservice/mojo/sensor.mojom.h>
#include <mojo/public/cpp/bindings/pending_receiver.h>
#include <mojo/public/cpp/bindings/pending_remote.h>
#include <mojo/public/cpp/bindings/receiver.h>
#include <mojo/public/cpp/bindings/remote.h>

#include "common/sensor_reader.h"
#include "cros-camera/camera_mojo_channel_manager.h"
#include "cros-camera/future.h"
#include "cros-camera/sensor_hal_client.h"

namespace cros {

class CameraMojoChannelManager;

class SensorHalClientImpl final : public SensorHalClient {
 public:
  explicit SensorHalClientImpl(CameraMojoChannelManager* mojo_manager);
  SensorHalClientImpl(const SensorHalClientImpl&) = delete;
  SensorHalClientImpl& operator=(const SensorHalClientImpl&) = delete;

  ~SensorHalClientImpl();

  // SensorHalClient implementations.
  bool HasDevice(DeviceType type, Location location);
  bool RegisterSamplesObserver(DeviceType type,
                               Location location,
                               double frequency,
                               SamplesObserver* samples_observer);
  void UnregisterSamplesObserver(SamplesObserver* samples_observer);

 private:
  // IPCBridge wraps all the IPC-related calls. Most of its methods should/will
  // be run on IPC thread.
  class IPCBridge : public mojom::SensorHalClient,
                    public mojom::SensorServiceNewDevicesObserver {
   public:
    IPCBridge(CameraMojoChannelManager* mojo_manager,
              CancellationRelay* cancellation_relay);

    // It should only be triggered on IPC thread to ensure thread-safety.
    ~IPCBridge();

    // Will only be called once, right after the c'tor.
    void Start();

    void HasDevice(mojom::DeviceType type,
                   Location location,
                   base::OnceCallback<void(bool)> callback);
    void RegisterSamplesObserver(mojom::DeviceType type,
                                 Location location,
                                 double frequency,
                                 SamplesObserver* samples_observer,
                                 base::OnceCallback<void(bool)> callback);
    void UnregisterSamplesObserver(SamplesObserver* samples_observer);

    // SensorHalClient Mojo interface implementation.
    void SetUpChannel(
        mojo::PendingRemote<mojom::SensorService> pending_remote) final;

    // SensorServiceNewDevicesObserver Mojo interface implementation.
    void OnNewDeviceAdded(int32_t iio_device_id,
                          const std::vector<mojom::DeviceType>& types) final;

    bool ClientIsBound() { return receiver_.is_bound(); }
    bool IsReady() { return sensor_service_remote_.is_bound(); }

    // Gets a weak pointer of the IPCBridge. This method can be called on
    // non-IPC thread.
    base::WeakPtr<IPCBridge> GetWeakPtr();

   private:
    struct DeviceData {
      bool ignored = false;

      std::vector<mojom::DeviceType> types;
      base::Optional<Location> location;
      base::Optional<double> scale;

      // Temporarily stores the remote, waiting for its attributes information.
      // It'll be passed to SensorDevice's constructor as an argument after all
      // information is collected, if this device is needed.
      mojo::Remote<mojom::SensorDevice> remote;
    };

    struct DeviceQueryInfo {
      mojom::DeviceType type;
      Location location;
      base::OnceCallback<void(bool)> callback;
    };

    struct ReaderData {
      int32_t iio_device_id;
      mojom::DeviceType type;
      double frequency;
      std::unique_ptr<SensorReader> sensor_reader;
    };

    void OnDeviceQueryTimedOut(uint32_t info_id);

    void RegisterDevice(int32_t iio_device_id,
                        const std::vector<mojom::DeviceType>& types);

    void GetAllDeviceIdsCallback(
        const base::flat_map<int32_t, std::vector<mojom::DeviceType>>&
            iio_device_ids_types);

    mojo::Remote<mojom::SensorDevice> GetSensorDeviceRemote(
        int32_t iio_device_id);

    void GetAttributesCallback(
        int32_t iio_device_id,
        const std::vector<std::string> attr_names,
        const std::vector<base::Optional<std::string>>& values);

    void IgnoreDevice(int32_t iio_device_id);
    // Return true if all devices of |type| are initialized and attributes are
    // ready. We can further process the queries of |type|.
    bool AreAllDevicesOfTypeInitialized(mojom::DeviceType type);

    void RunDeviceQueriesForType(mojom::DeviceType type);

    bool HasDeviceInternal(mojom::DeviceType type, Location location);

    void OnClientRegistered(int32_t result);
    void OnServiceMojoChannelError();

    void ResetSensorService();

    void OnSensorServiceDisconnect();
    void OnNewDevicesObserverDisconnect();
    void OnSensorDeviceDisconnect(int32_t iio_device_id,
                                  uint32_t custom_reason_code,
                                  const std::string& description);

    CameraMojoChannelManager* mojo_manager_;
    CancellationRelay* cancellation_relay_;

    // The Mojo IPC task runner.
    const scoped_refptr<base::SingleThreadTaskRunner> ipc_task_runner_;

    mojo::Receiver<mojom::SensorHalClient> receiver_{this};
    mojo::Remote<mojom::SensorService> sensor_service_remote_;

    // The Mojo channel to get notified when new devices are added to IIO
    // Service.
    mojo::Receiver<mojom::SensorServiceNewDevicesObserver>
        new_devices_observer_{this};

    uint32_t device_query_info_counter_ = 0;
    // First is the info id, second is the pending HasDevice query.
    std::map<uint32_t, DeviceQueryInfo> device_queries_info_;

    // Maps from DeviceType and Location to id.
    std::map<mojom::DeviceType, std::map<Location, int32_t>> device_maps_;

    bool devices_retrieved_ = false;

    // First is iio_device_id, second is the device's attributes and Mojo
    // remote.
    std::map<int32_t, DeviceData> devices_;

    // First is the observer's pointer, second is the specific sensor reader.
    std::map<SamplesObserver*, ReaderData> readers_;

    base::WeakPtrFactory<IPCBridge> weak_ptr_factory_{this};
  };

  CameraMojoChannelManager* mojo_manager_;

  std::unique_ptr<CancellationRelay> cancellation_relay_;

  // The instance which deals with the IPC-related calls. It should always run
  // and be deleted on IPC thread.
  std::unique_ptr<IPCBridge> ipc_bridge_;
};

}  // namespace cros

#endif  // CAMERA_COMMON_SENSOR_HAL_CLIENT_IMPL_H_
