// Copyright 2021 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/sys/fuzzing/framework/testing/process-proxy.h"

#include <lib/syslog/cpp/macros.h>
#include <zircon/status.h>

#include "src/sys/fuzzing/framework/target/module.h"

namespace fuzzing {

FakeProcessProxy::FakeProcessProxy(ExecutorPtr executor, ModulePoolPtr pool)
    : binding_(this), eventpair_(std::move(executor)), pool_(std::move(pool)) {}

bool FakeProcessProxy::has_module(FakeFrameworkModule* module) const {
  auto id = module->id();
  auto iter = ids_.find(id[0]);
  return iter != ids_.end() && iter->second == id[1];
}

void FakeProcessProxy::Configure(OptionsPtr options) { options_ = std::move(options); }

fidl::InterfaceRequestHandler<Instrumentation> FakeProcessProxy::GetHandler() {
  return [this](fidl::InterfaceRequest<Instrumentation> request) {
    binding_.Bind(std::move(request));
  };
}

void FakeProcessProxy::FakeProcessProxy::Initialize(InstrumentedProcess instrumented,
                                                    InitializeCallback callback) {
  // The coverage component invokes the callback, but the process waits for the engine's signal.
  callback(CopyOptions(*options_));
  auto* eventpair = instrumented.mutable_eventpair();
  eventpair_.Pair(std::move(*eventpair));
  zx_info_handle_basic_t info;
  auto status =
      instrumented.process().get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info), nullptr, nullptr);
  FX_DCHECK(status == ZX_OK) << zx_status_get_string(status);
  process_koid_ = info.koid;
  status = SignalPeer(kSync);
  FX_DCHECK(status == ZX_OK) << zx_status_get_string(status);
}

void FakeProcessProxy::AddLlvmModule(LlvmModule llvm_module, AddLlvmModuleCallback callback) {
  // The coverage component invokes the callback, but the process waits for the engine's signal.
  callback();
  SharedMemory counters;
  auto* inline_8bit_counters = llvm_module.mutable_inline_8bit_counters();
  auto status = counters.Link(std::move(*inline_8bit_counters));
  FX_DCHECK(status == ZX_OK) << zx_status_get_string(status);
  auto id = llvm_module.id();
  ids_[id[0]] = id[1];
  auto* module = pool_->Get(id, counters.size());
  module->Add(counters.data(), counters.size());
  counters_.push_back(std::move(counters));
  status = SignalPeer(kSync);
  FX_DCHECK(status == ZX_OK) << zx_status_get_string(status);
}

zx_status_t FakeProcessProxy::SignalPeer(Signal signal) {
  auto status = eventpair_.SignalPeer(0, signal);
  if (completer_) {
    completer_.complete_ok(signal);
  }
  return status;
}

Promise<> FakeProcessProxy::AwaitReceived(Signal signal) {
  return eventpair_.WaitFor(signal)
      .and_then([this](const zx_signals_t& observed) {
        return AsZxResult(eventpair_.SignalSelf(observed, 0));
      })
      .or_else([](const zx_status_t& status) { return fpromise::error(); })
      .wrap_with(scope_);
}

Promise<> FakeProcessProxy::AwaitSent(Signal signal) {
  Bridge<zx_signals_t> bridge;
  completer_ = std::move(bridge.completer);
  return bridge.consumer.promise_or(fpromise::error())
      .and_then([signal](const zx_signals_t& observed) -> Result<> {
        if (signal != observed) {
          return fpromise::error();
        }
        return fpromise::ok();
      });
}

}  // namespace fuzzing
