// Copyright 2019 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.

#include "src/media/audio/audio_core/plug_detector.h"

#include <fcntl.h>
#include <fuchsia/hardware/audio/cpp/fidl.h>
#include <lib/fdio/fdio.h>
#include <lib/fit/defer.h>
#include <lib/zx/channel.h>
#include <zircon/compiler.h>

#include <memory>
#include <vector>

#include <fbl/unique_fd.h>
#include <trace/event.h>

#include "src/lib/fsl/io/device_watcher.h"
#include "src/lib/syslog/cpp/logger.h"
#include "src/media/audio/audio_core/reporter.h"

namespace media::audio {
namespace {

static const struct {
  const char* path;
  bool is_input;
} AUDIO_DEVNODES[] = {
    {.path = "/dev/class/audio-output", .is_input = false},
    {.path = "/dev/class/audio-input", .is_input = true},
};

class PlugDetectorImpl : public PlugDetector {
 public:
  zx_status_t Start(Observer observer) final {
    TRACE_DURATION("audio", "PlugDetectorImpl::Start");
    // Start should only be called once.
    FX_DCHECK(watchers_.empty());
    FX_DCHECK(!observer_);
    FX_DCHECK(observer);

    observer_ = std::move(observer);

    // If we fail to set up monitoring for any of our target directories,
    // automatically stop monitoring all sources of device nodes.
    auto error_cleanup = fit::defer([this]() { Stop(); });

    // Create our watchers.
    for (const auto& devnode : AUDIO_DEVNODES) {
      auto watcher = fsl::DeviceWatcher::Create(
          devnode.path,
          [this, is_input = devnode.is_input](int dir_fd, const std::string& filename) {
            AddAudioDevice(dir_fd, filename, is_input);
          });

      if (watcher == nullptr) {
        FX_LOGS(ERROR) << "PlugDetectorImpl failed to create DeviceWatcher for \"" << devnode.path
                       << "\".";
        return ZX_ERR_NO_MEMORY;
      }

      watchers_.emplace_back(std::move(watcher));
    }

    error_cleanup.cancel();

    return ZX_OK;
  }

  void Stop() final {
    TRACE_DURATION("audio", "PlugDetectorImpl::Stop");
    observer_ = nullptr;
    watchers_.clear();
  }

 private:
  void AddAudioDevice(int dir_fd, const std::string& name, bool is_input) {
    TRACE_DURATION("audio", "PlugDetectorImpl::AddAudioDevice");
    if (!observer_) {
      return;
    }

    // Open the device node.
    //
    // TODO(35145): Remove blocking 'openat' from the main thread. fdio_open_at is probably what we
    // want, but we'll need a version of DeviceWatcher that operates on fuchsia::io::Directory
    // handles instead of file descriptors.
    fbl::unique_fd dev_node(openat(dir_fd, name.c_str(), O_RDONLY));
    if (!dev_node.is_valid()) {
      REP(FailedToOpenDevice(name, is_input, errno));
      FX_LOGS(ERROR) << "PlugDetectorImpl failed to open device node at \"" << name << "\". ("
                     << strerror(errno) << " : " << errno << ")";
      return;
    }

    // Obtain the FDIO device channel, wrap it in a sync proxy, use that to get the stream channel.
    zx_status_t res;
    zx::channel dev_channel;
    res = fdio_get_service_handle(dev_node.release(), dev_channel.reset_and_get_address());
    if (res != ZX_OK) {
      REP(FailedToObtainFdioServiceChannel(name, is_input, res));
      FX_PLOGS(ERROR, res) << "Failed to obtain FDIO service channel to audio "
                           << (is_input ? "input" : "output");
      return;
    }

    // Obtain the stream channel
    auto device =
        fidl::InterfaceHandle<fuchsia::hardware::audio::Device>(std::move(dev_channel)).Bind();
    device.set_error_handler([name, is_input](zx_status_t res) {
      REP(FailedToObtainStreamChannel(name, is_input, res));
      FX_PLOGS(ERROR, res) << "Failed to open channel to audio " << (is_input ? "input" : "output");
    });
    device->GetChannel([d = std::move(device), this, is_input, name](
                           ::fidl::InterfaceHandle<fuchsia::hardware::audio::StreamConfig> intf) {
      observer_(intf.TakeChannel(), name, is_input);
    });
  }
  Observer observer_;
  std::vector<std::unique_ptr<fsl::DeviceWatcher>> watchers_;
};

}  // namespace

std::unique_ptr<PlugDetector> PlugDetector::Create() {
  return std::make_unique<PlugDetectorImpl>();
}

}  // namespace media::audio
