// Copyright 2024 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/devices/bin/driver_manager/controller_allowlist_passthrough.h"

#include <zircon/assert.h>

#include <memory>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>

#include "lib/fidl/cpp/wire/internal/transport.h"
#include "src/devices/lib/log/log.h"
#include "zircon/errors.h"

namespace {

const char *kAllowAllUses = "Allow_all_uses";

// Listed below are all the class names of _servers_ of the fuchsia.device/Controller protocol
// that are allowed for each function.  There can be and often are multiple clients that use
// a function of the protocol for each entry.  As a comment after each entry, please list
// at least one client or test that uses the function of the listed class name.  This makes it
// easier to track what clients may be affected by removing an interface. See
// https://fxbug.dev/331409420 for more information about migrating off of the
// fuchsia.device/Controller protocol.
const std::unordered_map<std::string, std::unordered_set<std::string_view>> kControllerAllowlists({
    {"ConnectToController",
     {
         "block",  // zxcrypt-test
         "No_class_name_but_driver_url_is_fuchsia-boot:///dtr#meta/sample-driver.cm",  // device_controller_fidl
         "driver_runner_test",  // driver-runner-test
     }},
    {"ConnectToDeviceFidl",
     {
         "block",               // Allow qemu to boot
         "driver_runner_test",  // driver_runner_death_test
         "nand",                // Some internal bot
         "No_class_name_but_driver_url_is_fuchsia-boot:///dtr#meta/fvm.cm",  // paver-test
         "No_class_name_but_driver_url_is_fuchsia-boot:///fvm#meta/fvm.cm",  // installer_test.sh
         "No_class_name_but_driver_url_is_fuchsia-boot:///gpt#meta/gpt.cm",  // storage-verity-benchmarks
         "No_class_name_but_driver_url_is_fuchsia-boot:///dtr#meta/nand-broker.cm",  // nand-broker-test
         "No_class_name_but_driver_url_is_fuchsia-boot:///dtr#meta/sample-driver.cm",
     }},
    {"Bind",
     {
         "block",                                                             // allow vim3 to boot
         "No_class_name_but_driver_url_is_fuchsia-boot:///dtr#meta/test.cm",  //  bind-fail-test
         "driver_runner_test",                                                // driver-runner-test
         "test",  // power-manager-integration-test
     }},
    {"Rebind", {kAllowAllUses}},
    {"UnbindChildren",
     {
         "block",               // fshost_integration_tests_fxfs_no_fxblob.cm
         "driver_runner_test",  // driver-runner-test
     }},
    {"ScheduleUnbind",
     {
         "bt-emulator",         // bt-host-integration-tests
         "driver_runner_test",  // driver-runner-test
         "nand",                // ram-nand-test
         "No_class_name_but_driver_url_is_fuchsia-boot:///dtr#meta/ddk-lifecycle-test.cm",  // ddk-lifecycle-test
         "No_class_name_but_driver_url_is_fuchsia-boot:///dtr#meta/fvm.cm",  // paver-test
         "No_class_name_but_driver_url_is_fuchsia-boot:///fvm#meta/fvm.cm",
         "No_class_name_but_driver_url_is_unbound",  // blobfs-ramdisk-test, and so many others
     }},
    {"GetTopologicalPath", {kAllowAllUses}},
});

}  // namespace

void ControllerAllowlistPassthrough::CheckAllowlist(const std::string &function_name) {
  auto allowlist = kControllerAllowlists.find(function_name);
  ZX_ASSERT_MSG(allowlist != kControllerAllowlists.end(), "Function %s was not on the allowlist",
                function_name.c_str());
  // If the kAllowAllUses string is present, just skip the check for that function.
  if (allowlist->second.find(kAllowAllUses) != allowlist->second.end()) {
    return;
  }
  ZX_ASSERT_MSG(allowlist->second.find(class_name_) != allowlist->second.end(),
                "\nUndeclared DEVFS_USAGE detected: %s is using %s.\n"
                "This error is thrown when a fuchsia.device/Controller client\n"
                "attempts to access a device and function not registered at\n"
                "src/devices/bin/driver_manager/controller_allowlist_passthrough.cc.\n"
                "If you need to add to the allowlist, add a bug as a child under "
                "https://fxbug.dev/331409420. To learn more, see: "
                "sdk/fidl/fuchsia.device.fs/README.md\n",
                class_name_.c_str(), function_name.c_str());
}

void ControllerAllowlistPassthrough::ConnectToDeviceFidl(
    ConnectToDeviceFidlRequestView request, ConnectToDeviceFidlCompleter::Sync &completer) {
  CheckAllowlist("ConnectToDeviceFidl");
  if (compat_client_.is_valid()) {
    fidl::OneWayStatus status = compat_client_->ConnectToDeviceFidl(std::move(request->server));
    if (!status.ok()) {
      LOGF(ERROR, "Failed to forward ConnectToDeviceFidl call for %s.", class_name_.c_str());
    }
  } else {
    std::shared_ptr locked_node = node_.lock();
    if (!locked_node) {
      LOGF(ERROR, "Node was freed before it was used for %s.", class_name_.c_str());
      return;
    }
    locked_node->ConnectToDeviceFidl(request, completer);
  }
}

void ControllerAllowlistPassthrough::ConnectToController(
    ConnectToControllerRequestView request, ConnectToControllerCompleter::Sync &completer) {
  CheckAllowlist("ConnectToController");
  dev_controller_bindings_.AddBinding(dispatcher_, std::move(request->server), this,
                                      fidl::kIgnoreBindingClosure);
}

void ControllerAllowlistPassthrough::Bind(BindRequestView request, BindCompleter::Sync &completer) {
  CheckAllowlist("Bind");
  if (compat_client_.is_valid()) {
    compat_client_->Bind(request->driver)
        .ThenExactlyOnce([completer = completer.ToAsync()](auto &result) mutable {
          if (!result.ok()) {
            completer.ReplyError(result.status());
            return;
          }
          completer.Reply(result.value());
        });
  } else {
    std::shared_ptr locked_node = node_.lock();
    if (!locked_node) {
      LOGF(ERROR, "Node was freed before it was used for %s.", class_name_.c_str());
      return;
    }
    locked_node->Bind(request, completer);
  }
}
void ControllerAllowlistPassthrough::Rebind(RebindRequestView request,
                                            RebindCompleter::Sync &completer) {
  CheckAllowlist("Rebind");
  if (compat_client_.is_valid()) {
    compat_client_->Rebind(request->driver)
        .ThenExactlyOnce(
            [completer = completer.ToAsync()](
                fidl::WireUnownedResult<fuchsia_device::Controller::Rebind> &result) mutable {
              if (!result.ok()) {
                completer.ReplyError(result.status());
                return;
              }
              completer.Reply(result.value());
            });
  } else {
    std::shared_ptr locked_node = node_.lock();
    if (!locked_node) {
      LOGF(ERROR, "Node was freed before it was used for %s.", class_name_.c_str());
      return;
    }
    locked_node->Rebind(request, completer);
  }
}
void ControllerAllowlistPassthrough::UnbindChildren(UnbindChildrenCompleter::Sync &completer) {
  CheckAllowlist("UnbindChildren");
  if (compat_client_.is_valid()) {
    compat_client_->UnbindChildren().ThenExactlyOnce(
        [completer = completer.ToAsync()](auto &result) mutable {
          if (!result.ok()) {
            completer.ReplyError(result.status());
            return;
          }
          completer.Reply(result.value());
        });
  } else {
    std::shared_ptr locked_node = node_.lock();
    if (!locked_node) {
      LOGF(ERROR, "Node was freed before it was used for %s.", class_name_.c_str());
      return;
    }
    locked_node->UnbindChildren(completer);
  }
}
void ControllerAllowlistPassthrough::ScheduleUnbind(ScheduleUnbindCompleter::Sync &completer) {
  CheckAllowlist("ScheduleUnbind");
  if (compat_client_.is_valid()) {
    compat_client_->ScheduleUnbind().ThenExactlyOnce(
        [completer = completer.ToAsync()](auto &result) mutable {
          if (!result.ok()) {
            completer.ReplyError(result.status());
            return;
          }
          completer.Reply(result.value());
        });
  } else {
    std::shared_ptr locked_node = node_.lock();
    if (!locked_node) {
      LOGF(ERROR, "Node was freed before it was used for %s.", class_name_.c_str());
      return;
    }
    locked_node->ScheduleUnbind(completer);
  }
}
void ControllerAllowlistPassthrough::GetTopologicalPath(
    GetTopologicalPathCompleter::Sync &completer) {
  CheckAllowlist("GetTopologicalPath");
  if (compat_client_.is_valid()) {
    compat_client_->GetTopologicalPath().ThenExactlyOnce(
        [completer = completer.ToAsync()](auto &result) mutable {
          if (!result.ok()) {
            completer.ReplyError(result.status());
            return;
          }
          completer.Reply(result.value());
        });
  } else {
    std::shared_ptr locked_node = node_.lock();
    if (!locked_node) {
      LOGF(ERROR, "Node was freed before it was used for %s.", class_name_.c_str());
      return;
    }
    locked_node->GetTopologicalPath(completer);
  }
}

zx_status_t ControllerAllowlistPassthrough::Connect(
    fidl::ServerEnd<fuchsia_device::Controller> server_end) {
  dev_controller_bindings_.AddBinding(dispatcher_, std::move(server_end), this,
                                      fidl::kIgnoreBindingClosure);
  return ZX_OK;
}

std::unique_ptr<ControllerAllowlistPassthrough> ControllerAllowlistPassthrough::Create(
    std::optional<fidl::ClientEnd<fuchsia_device_fs::Connector>> controller_connector,
    std::weak_ptr<fidl::WireServer<fuchsia_device::Controller>> node,
    async_dispatcher_t *dispatcher, const std::string &class_name) {
  std::unique_ptr<ControllerAllowlistPassthrough> ret(
      new ControllerAllowlistPassthrough(std::move(node), dispatcher, class_name));
  if (!controller_connector.has_value()) {
    return ret;
  }
  auto [client_end, server_end] = fidl::Endpoints<fuchsia_device::Controller>::Create();

  zx_status_t status =
      fidl::WireCall(controller_connector.value())->Connect(server_end.TakeChannel()).status();
  if (status != ZX_OK) {
    return ret;
  }
  ret->compat_client_.Bind(std::move(client_end), dispatcher);
  return ret;
}
