// Copyright 2017 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 <ddk/binding.h>
#include <ddk/device.h>
#include <ddk/driver.h>
#include <ddk/protocol/test.h>
#include <ddktl/device.h>
#include <lib/zx/socket.h>

#include <limits.h>
#include <memory>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unittest/unittest.h>

extern test_case_element* test_case_ddktl_device;
extern test_case_element* test_case_ddktl_ethernet_device;

namespace {

void ddktl_test_output_func(const char* line, int len, void* arg) {
  zx_handle_t h = *static_cast<zx_handle_t*>(arg);
  zx::unowned_socket s(h);
  // len is not actually the number of bytes to output
  s->write(0u, line, strlen(line), nullptr);
}

static void inline update_test_report(bool success, test_report_t* report) {
  report->n_tests++;
  if (success) {
    report->n_success++;
  } else {
    report->n_failed++;
  }
}

zx_status_t ddktl_test_func(void* cookie, test_report_t* report) {
  auto dev = static_cast<zx_device_t*>(cookie);

  test_protocol_t proto;
  auto status = device_get_protocol(dev, ZX_PROTOCOL_TEST, reinterpret_cast<void*>(&proto));
  if (status != ZX_OK) {
    return status;
  }

  zx_handle_t output;
  proto.ops->get_output_socket(proto.ctx, &output);
  if (output != ZX_HANDLE_INVALID) {
    unittest_set_output_function(ddktl_test_output_func, &output);
  }

  memset(report, 0, sizeof(*report));
  update_test_report(unittest_run_one_test(test_case_ddktl_device, TEST_ALL), report);
  update_test_report(unittest_run_one_test(test_case_ddktl_ethernet_device, TEST_ALL), report);
  unittest_restore_output_function();
  zx_handle_close(output);
  return report->n_failed == 0 ? ZX_OK : ZX_ERR_INTERNAL;
}

class ChildDevice;
using ChildDeviceType = ddk::Device<ChildDevice, ddk::Unbindable>;

class ChildDevice : public ChildDeviceType {
 public:
  ChildDevice(zx_device_t* parent) : ChildDeviceType(parent) {}
  void DdkUnbind() { DdkRemove(); }
  void DdkRelease() { delete this; }
};

}  // namespace

extern "C" zx_status_t ddktl_test_bind(void* ctx, zx_device_t* parent) {
  auto device = std::make_unique<ChildDevice>(parent);
  zx_status_t status = device->DdkAdd("child", DEVICE_ADD_NON_BINDABLE);
  if (status != ZX_OK) {
    return status;
  }
  // devmgr now owns this
  __UNUSED auto ptr = device.release();

  test_protocol_t proto;
  status = device_get_protocol(parent, ZX_PROTOCOL_TEST, &proto);
  if (status != ZX_OK) {
    return status;
  }

  const test_func_t test = {ddktl_test_func, parent};
  proto.ops->set_test_func(proto.ctx, &test);
  return ZX_OK;
}
