// 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 "composite_device.h"

#include <lib/fidl/llcpp/arena.h>
#include <zircon/status.h>

#include <string_view>
#include <utility>

#include "binding_internal.h"
#include "coordinator.h"
#include "src/devices/lib/log/log.h"

namespace fdm = fuchsia_device_manager;

namespace {

fbl::Array<StrProperty> ConvertStringProperties(
    fidl::VectorView<fdm::wire::DeviceStrProperty> str_props) {
  fbl::Array<StrProperty> str_properties(new StrProperty[str_props.count()], str_props.count());
  for (size_t i = 0; i < str_props.count(); i++) {
    str_properties[i].key = str_props[i].key.get();
    if (str_props[i].value.is_int_value()) {
      str_properties[i].value.emplace<StrPropValueType::Integer>(str_props[i].value.int_value());
    } else if (str_props[i].value.is_str_value()) {
      str_properties[i].value.emplace<StrPropValueType::String>(
          std::string(str_props[i].value.str_value().get()));
    } else if (str_props[i].value.is_bool_value()) {
      str_properties[i].value.emplace<StrPropValueType::Bool>(str_props[i].value.bool_value());
    } else if (str_props[i].value.is_enum_value()) {
      str_properties[i].value.emplace<StrPropValueType::Enum>(
          std::string(str_props[i].value.enum_value().get()));
    }
  }

  return str_properties;
}

}  // namespace

// CompositeDevice methods

CompositeDevice::CompositeDevice(fbl::String name, fbl::Array<const zx_device_prop_t> properties,
                                 fbl::Array<const StrProperty> str_properties,
                                 uint32_t fragments_count, uint32_t primary_fragment_index,
                                 bool spawn_colocated,
                                 fbl::Array<std::unique_ptr<Metadata>> metadata,
                                 bool from_driver_index)
    : name_(std::move(name)),
      properties_(std::move(properties)),
      str_properties_(std::move(str_properties)),
      fragments_count_(fragments_count),
      primary_fragment_index_(primary_fragment_index),
      spawn_colocated_(spawn_colocated),
      metadata_(std::move(metadata)),
      from_driver_index_(from_driver_index) {}

CompositeDevice::~CompositeDevice() = default;

zx_status_t CompositeDevice::Create(std::string_view name,
                                    fdm::wire::CompositeDeviceDescriptor comp_desc,
                                    std::unique_ptr<CompositeDevice>* out) {
  fbl::String name_obj(name);
  fbl::Array<zx_device_prop_t> properties(new zx_device_prop_t[comp_desc.props.count() + 1],
                                          comp_desc.props.count() + 1);
  memcpy(properties.data(), comp_desc.props.data(),
         comp_desc.props.count() * sizeof(comp_desc.props.data()[0]));

  // Set a property unique to composite devices.
  properties[comp_desc.props.count()].id = BIND_COMPOSITE;
  properties[comp_desc.props.count()].value = 1;

  fbl::Array<std::unique_ptr<Metadata>> metadata(
      new std::unique_ptr<Metadata>[comp_desc.metadata.count()], comp_desc.metadata.count());

  fbl::Array<StrProperty> str_properties = ConvertStringProperties(comp_desc.str_props);

  for (size_t i = 0; i < comp_desc.metadata.count(); i++) {
    std::unique_ptr<Metadata> md;
    zx_status_t status = Metadata::Create(comp_desc.metadata[i].data.count(), &md);
    if (status != ZX_OK) {
      return status;
    }

    md->type = comp_desc.metadata[i].key;
    md->length = comp_desc.metadata[i].data.count();
    memcpy(md->Data(), comp_desc.metadata[i].data.data(), md->length);
    metadata[i] = std::move(md);
  }

  auto dev = std::make_unique<CompositeDevice>(
      std::move(name), std::move(properties), std::move(str_properties),
      comp_desc.fragments.count(), comp_desc.primary_fragment_index, comp_desc.spawn_colocated,
      std::move(metadata), false);
  for (uint32_t i = 0; i < comp_desc.fragments.count(); ++i) {
    const auto& fidl_fragment = comp_desc.fragments[i];
    size_t parts_count = fidl_fragment.parts.count();
    if (parts_count != 1) {
      LOGF(ERROR, "Composite fragments with multiple parts are deprecated. %s has %zd parts.",
           name.data(), parts_count);
      return ZX_ERR_INVALID_ARGS;
    }

    const auto& fidl_part = fidl_fragment.parts[0];
    size_t program_count = fidl_part.match_program.count();
    fbl::Array<zx_bind_inst_t> bind_rules(new zx_bind_inst_t[program_count], program_count);
    for (size_t j = 0; j < program_count; ++j) {
      bind_rules[j] = zx_bind_inst_t{
          .op = fidl_part.match_program[j].op,
          .arg = fidl_part.match_program[j].arg,
      };
    }
    std::string name(fidl_fragment.name.data(), fidl_fragment.name.size());
    auto fragment =
        std::make_unique<CompositeDeviceFragment>(dev.get(), name, i, std::move(bind_rules));
    dev->unbound_fragments_.push_back(std::move(fragment));
  }
  *out = std::move(dev);
  return ZX_OK;
}

zx::status<std::unique_ptr<CompositeDevice>> CompositeDevice::CreateForDeviceGroup(
    std::string_view name, fuchsia_device_manager::wire::DeviceGroupDescriptor group_desc) {
  fbl::String name_obj(name);

  fbl::Array<zx_device_prop_t> properties(new zx_device_prop_t[group_desc.props.count() + 1],
                                          group_desc.props.count() + 1);
  memcpy(properties.data(), group_desc.props.data(),
         group_desc.props.count() * sizeof(group_desc.props.data()[0]));

  // Set a property unique to composite devices.
  properties[group_desc.props.count()].id = BIND_COMPOSITE;
  properties[group_desc.props.count()].value = 1;

  fbl::Array<std::unique_ptr<Metadata>> metadata(
      new std::unique_ptr<Metadata>[group_desc.metadata.count()], group_desc.metadata.count());

  fbl::Array<StrProperty> str_properties = ConvertStringProperties(group_desc.str_props);

  for (size_t i = 0; i < group_desc.metadata.count(); i++) {
    std::unique_ptr<Metadata> md;
    zx_status_t status = Metadata::Create(group_desc.metadata[i].data.count(), &md);
    if (status != ZX_OK) {
      return zx::error(status);
      ;
    }

    md->type = group_desc.metadata[i].key;
    md->length = group_desc.metadata[i].data.count();
    memcpy(md->Data(), group_desc.metadata[i].data.data(), md->length);
    metadata[i] = std::move(md);
  }

  auto dev = std::make_unique<CompositeDevice>(
      std::move(name), std::move(properties), std::move(str_properties),
      group_desc.fragments.count(), 0, group_desc.spawn_colocated, std::move(metadata), false);
  for (uint32_t i = 0; i < group_desc.fragments.count(); ++i) {
    const auto& node = group_desc.fragments[i];
    std::string name(node.name.data(), node.name.size());
    auto fragment = std::make_unique<CompositeDeviceFragment>(dev.get(), name, i,
                                                              fbl::Array<const zx_bind_inst_t>());
    dev->unbound_fragments_.push_back(std::move(fragment));
  }

  return zx::ok(std::move(dev));
}

zx_status_t CompositeDevice::CreateFromDriverIndex(MatchedCompositeDriverInfo driver,
                                                   std::unique_ptr<CompositeDevice>* out) {
  fbl::String name(driver.composite.name);
  auto dev = std::make_unique<CompositeDevice>(
      std::move(name), fbl::Array<const zx_device_prop_t>(), fbl::Array<const StrProperty>(),
      driver.composite.num_nodes, 0, driver.driver_info.colocate,
      fbl::Array<std::unique_ptr<Metadata>>(), true);

  for (uint32_t i = 0; i < driver.composite.num_nodes; ++i) {
    std::string name = driver.composite.node_names[i];
    auto fragment = std::make_unique<CompositeDeviceFragment>(dev.get(), std::string(name), i,
                                                              fbl::Array<const zx_bind_inst_t>());
    dev->unbound_fragments_.push_back(std::move(fragment));
  }
  dev->driver_index_driver_ = driver.driver_info.driver;

  *out = std::move(dev);
  return ZX_OK;
}

bool CompositeDevice::IsFragmentMatch(const fbl::RefPtr<Device>& dev, size_t* index_out) const {
  if (from_driver_index_) {
    return false;
  }

  for (auto itr = bound_fragments_.begin(); itr != bound_fragments_.end(); ++itr) {
    if (itr->TryMatch(dev)) {
      LOGF(ERROR, "Ambiguous bind for composite device %p '%s': device 1 '%s', device 2 '%s'", this,
           name_.data(), itr->bound_device()->name().data(), dev->name().data());
      return false;
    }
  }
  for (auto itr = unbound_fragments_.begin(); itr != unbound_fragments_.end(); ++itr) {
    if (itr->TryMatch(dev)) {
      VLOGF(1, "Found a match for composite device %p '%s': device '%s'", this, name_.data(),
            dev->name().data());
      *index_out = itr->index();
      return true;
    }
  }
  VLOGF(1, "No match for composite device %p '%s': device '%s'", this, name_.data(),
        dev->name().data());
  return false;
}

zx_status_t CompositeDevice::TryMatchBindFragments(const fbl::RefPtr<Device>& dev) {
  size_t index;
  if (!IsFragmentMatch(dev, &index)) {
    return ZX_OK;
  }

  LOGF(INFO, "Device '%s' matched fragment %zu of composite '%s'", dev->name().data(), index,
       name().data());
  auto status = BindFragment(index, dev);
  if (status != ZX_OK) {
    LOGF(ERROR, "Device '%s' failed to bind fragment %zu of composite '%s': %s", dev->name().data(),
         index, name().data(), zx_status_get_string(status));
  }
  return status;
}

zx_status_t CompositeDevice::BindFragment(size_t index, const fbl::RefPtr<Device>& dev) {
  // Find the fragment we're binding
  CompositeDeviceFragment* fragment = nullptr;
  for (auto& unbound_fragment : unbound_fragments_) {
    if (unbound_fragment.index() == index) {
      fragment = &unbound_fragment;
      break;
    }
  }

  if (!fragment) {
    LOGF(ERROR, "Attempted to bind bound fragment %zu in composite device %p", index, name_.data());
    return ZX_OK;
  }

  zx_status_t status = fragment->Bind(dev);
  if (status != ZX_OK) {
    return status;
  }
  bound_fragments_.push_back(unbound_fragments_.erase(*fragment));
  if (dev->has_outgoing_directory()) {
    TryAssemble();
  }

  return ZX_OK;
}

zx_status_t CompositeDevice::TryAssemble() {
  ZX_ASSERT(device_ == nullptr);
  if (!unbound_fragments_.is_empty()) {
    return ZX_ERR_SHOULD_WAIT;
  }

  for (auto& fragment : bound_fragments_) {
    // Make sure the fragment driver has created its device
    // or that it didn't need one.
    if (fragment.fragment_device() == nullptr &&
        !fragment.bound_device()->has_outgoing_directory()) {
      return ZX_ERR_SHOULD_WAIT;
    }
  }

  // Find the driver_host to put everything in, nullptr means "a new driver_host".
  fbl::RefPtr<DriverHost> driver_host;
  if (spawn_colocated_) {
    for (auto& fragment : bound_fragments_) {
      if (fragment.index() == primary_fragment_index_) {
        driver_host = fragment.bound_device()->host();
      }
    }
  }

  Coordinator* coordinator = nullptr;

  fidl::Arena allocator;
  fidl::VectorView<fdm::wire::Fragment> fragments(allocator, bound_fragments_.size_slow());

  // Create all of the proxies for the fragment devices, in the same process
  for (auto& fragment : bound_fragments_) {
    const auto& fragment_dev = fragment.fragment_device();
    auto bound_dev = fragment.bound_device();
    coordinator = bound_dev->coordinator;

    // If the device we're bound to is proxied, we care about its proxy
    // rather than it, since that's the side that we communicate with.
    if (bound_dev->proxy()) {
      bound_dev = bound_dev->proxy();
    }

    if (bound_dev->new_proxy()) {
      bound_dev = bound_dev->new_proxy();
    }

    // Check if we need to use the proxy.  If not, share a reference to
    // the instance of the fragment device.
    // We always use a proxy when there is an outgoing directory involved.
    if (bound_dev->host() == driver_host && !bound_dev->has_outgoing_directory()) {
      fragments[fragment.index()].name = fidl::StringView::FromExternal(fragment.name());
      fragments[fragment.index()].id = fragment_dev->local_id();
      continue;
    }

    // We need to create it.  Double check that we haven't ended up in a state
    // where the proxies would need to be in different processes.
    fbl::RefPtr<Device> proxy;
    zx_status_t status;
    if (bound_dev->has_outgoing_directory()) {
      if (driver_host != nullptr && bound_dev->new_proxy() != nullptr &&
          bound_dev->new_proxy()->host() != nullptr &&
          bound_dev->new_proxy()->host() != driver_host) {
        LOGF(ERROR, "Cannot create composite device, device proxies are in different driver_hosts");
        return ZX_ERR_BAD_STATE;
      }

      VLOGF(1, "Preparing new proxy for %s", bound_dev->name().data());
      status = coordinator->PrepareNewProxy(bound_dev, driver_host);
      if (status != ZX_OK) {
        return status;
      }
      proxy = bound_dev->new_proxy();
    } else {
      if (driver_host != nullptr && fragment_dev->proxy() != nullptr &&
          fragment_dev->proxy()->host() != nullptr &&
          fragment_dev->proxy()->host() != driver_host) {
        LOGF(ERROR, "Cannot create composite device, device proxies are in different driver_hosts");
        return ZX_ERR_BAD_STATE;
      }

      VLOGF(1, "Preparing old proxy for %s", fragment_dev->name().data());
      status = coordinator->PrepareProxy(fragment_dev, driver_host);
      if (status != ZX_OK) {
        return status;
      }

      proxy = fragment_dev->proxy();
    }

    // If we hadn't picked a driver_host, use the one that was created just now.
    if (driver_host == nullptr) {
      driver_host = proxy->host();
      ZX_ASSERT(driver_host != nullptr);
    }

    // Stash the local ID after the proxy has been created
    fragments[fragment.index()].name = fidl::StringView::FromExternal(fragment.name());
    fragments[fragment.index()].id = proxy->local_id();
  }

  auto coordinator_endpoints = fidl::CreateEndpoints<fdm::Coordinator>();
  if (coordinator_endpoints.is_error()) {
    return coordinator_endpoints.error_value();
  }

  auto device_controller_endpoints = fidl::CreateEndpoints<fdm::DeviceController>();
  if (device_controller_endpoints.is_error()) {
    return device_controller_endpoints.error_value();
  }

  fbl::RefPtr<Device> new_device;
  auto status = Device::CreateComposite(
      coordinator, driver_host, *this, std::move(coordinator_endpoints->server),
      std::move(device_controller_endpoints->client), &new_device);
  if (status != ZX_OK) {
    return status;
  }
  coordinator->device_manager()->AddToDevices(new_device);

  // Create the composite device in the driver_host
  fdm::wire::CompositeDevice composite{fragments, fidl::StringView::FromExternal(name())};
  auto type = fdm::wire::DeviceType::WithComposite(allocator, composite);

  driver_host->controller()
      ->CreateDevice(std::move(coordinator_endpoints->client),
                     std::move(device_controller_endpoints->server), std::move(type),
                     new_device->local_id())
      .ThenExactlyOnce(
          [](fidl::WireUnownedResult<fdm::DriverHostController::CreateDevice>& result) {
            if (!result.ok()) {
              LOGF(ERROR, "Failed to create composite device: %s",
                   result.error().FormatDescription().c_str());
              return;
            }
            if (result.value().status != ZX_OK) {
              LOGF(ERROR, "Failed to create composite device: %s",
                   zx_status_get_string(result.value().status));
            }
          });

  device_ = std::move(new_device);
  device_->set_composite(this);

  // Add metadata
  for (size_t i = 0; i < metadata_.size(); i++) {
    // Making a copy of metadata, instead of transfering ownership, so that
    // metadata can be added again if device is recreated
    status = coordinator->AddMetadata(device_, metadata_[i]->type, metadata_[i]->Data(),
                                      metadata_[i]->length);
    if (status != ZX_OK) {
      LOGF(ERROR, "Failed to add metadata to device %p '%s': %s", device_.get(),
           device_->name().data(), zx_status_get_string(status));
      return status;
    }
  }

  status = device_->SignalReadyForBind();
  if (status != ZX_OK) {
    return status;
  }
  if (from_driver_index_) {
    zx_status_t status = coordinator->AttemptBind(driver_index_driver_, device_);
    if (status != ZX_OK) {
      LOGF(ERROR, "%s: Failed to bind composite driver '%s' to device '%s': %s", __func__,
           driver_index_driver_->libname.data(), device_->name().data(),
           zx_status_get_string(status));
    }
    return status;
  }

  return ZX_OK;
}

void CompositeDevice::UnbindFragment(CompositeDeviceFragment* fragment) {
  // If the composite was fully instantiated, disassociate from it.  It will be
  // reinstantiated when this fragment is re-bound.
  if (device_ != nullptr) {
    Remove();
  }
  ZX_ASSERT(device_ == nullptr);
  ZX_ASSERT(fragment->composite() == this);
  unbound_fragments_.push_back(bound_fragments_.erase(*fragment));
}

void CompositeDevice::Remove() {
  if (device_ != nullptr) {
    device_->disassociate_from_composite();
    device_ = nullptr;
  }
}

// CompositeDeviceFragment methods

CompositeDeviceFragment::CompositeDeviceFragment(CompositeDevice* composite, std::string name,
                                                 uint32_t index,
                                                 fbl::Array<const zx_bind_inst_t> bind_rules)
    : composite_(composite), name_(name), index_(index), bind_rules_(std::move(bind_rules)) {}

CompositeDeviceFragment::~CompositeDeviceFragment() = default;

bool CompositeDeviceFragment::TryMatch(const fbl::RefPtr<Device>& dev) const {
  return internal::EvaluateBindProgram(dev, "composite_binder", bind_rules_, true /* autobind */);
}

zx_status_t CompositeDeviceFragment::Bind(const fbl::RefPtr<Device>& dev) {
  ZX_ASSERT(bound_device_ == nullptr);

  if (!dev->has_outgoing_directory()) {
    zx_status_t status = dev->coordinator->bind_driver_manager()->MatchAndBind(
        dev, dev->coordinator->fragment_driver(), false /* autobind */);
    if (status != ZX_OK) {
      return status;
    }
    bound_device_ = dev;
    dev->push_fragment(this);
  } else {
    bound_device_ = dev;
    dev->push_fragment(this);
    dev->flags |= DEV_CTX_BOUND;
  }

  return ZX_OK;
}

void CompositeDeviceFragment::Unbind() {
  ZX_ASSERT(bound_device_ != nullptr);
  composite_->UnbindFragment(this);
  // Drop our reference to the device added by the fragment driver
  fragment_device_ = nullptr;
  bound_device_->disassociate_from_composite();
  bound_device_ = nullptr;
}
