// 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 <fuchsia/io/cpp/fidl.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/async-loop/default.h>
#include <lib/async/default.h>
#include <lib/vfs/cpp/internal/directory_connection.h>
#include <lib/vfs/cpp/internal/file.h>
#include <lib/vfs/cpp/internal/file_connection.h>
#include <lib/vfs/cpp/internal/node.h>
#include <lib/vfs/cpp/internal/node_connection.h>
#include <lib/vfs/cpp/node_kind.h>
#include <lib/vfs/cpp/pseudo_dir.h>
#include <zircon/errors.h>
#include <zircon/types.h>

#include <gtest/gtest.h>

namespace {

class DummyTestFile : public vfs::internal::File {
 public:
  zx_status_t ReadAt(uint64_t count, uint64_t offset, std::vector<uint8_t>* out_data) override {
    return ZX_OK;
  }

  zx_status_t WriteAt(std::vector<uint8_t> data, uint64_t offset, uint64_t* out_actual) override {
    return ZX_OK;
  }

  uint64_t GetLength() override { return 0; }

  size_t GetCapacity() override { return 0; }
};

void CallBindTwiceAndTest(vfs::internal::Connection* connection) {
  fuchsia::io::NodePtr ptr1;
  fuchsia::io::NodePtr ptr2;
  ASSERT_EQ(ZX_OK,
            connection->Bind(ptr1.NewRequest().TakeChannel(), async_get_default_dispatcher()));
  ASSERT_EQ(ZX_ERR_BAD_STATE,
            connection->Bind(ptr2.NewRequest().TakeChannel(), async_get_default_dispatcher()));
}

TEST(ConnectionBindCalledTwice, DirectoryConnection) {
  vfs::PseudoDir dir;
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  vfs::internal::DirectoryConnection connection(0, &dir);

  CallBindTwiceAndTest(&connection);
}

TEST(ConnectionBindCalledTwice, FileConnection) {
  DummyTestFile file;
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  vfs::internal::FileConnection connection(0, &file);

  CallBindTwiceAndTest(&connection);
}

TEST(ConnectionBindCalledTwice, NodeConnection) {
  vfs::PseudoDir dir;
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  vfs::internal::NodeConnection connection(0, &dir);

  CallBindTwiceAndTest(&connection);
}

class DummyTestNode : public vfs::internal::Node {
 public:
  zx_status_t PreClose(vfs::internal::Connection* connection) override {
    return ZX_ERR_UNAVAILABLE;
  }

  void Describe(fuchsia::io::NodeInfo* out_info) override {}
  void Describe2(fuchsia::io::ConnectionInfo* out_info) override {}

  vfs::NodeKind::Type GetKind() const override { return vfs::NodeKind::kFile; }

  zx_status_t CreateConnection(uint32_t flags,
                               std::unique_ptr<vfs::internal::Connection>* connection) override {
    return Node::CreateConnection(flags, connection);
  }
};

TEST(ConenctionTest, ConnectionPassedErrorInClose) {
  DummyTestNode node;
  async::Loop loop(&kAsyncLoopConfigAttachToCurrentThread);
  loop.StartThread("vfs test thread");
  fuchsia::io::NodeSyncPtr ptr;
  ASSERT_EQ(ZX_OK, node.Serve(0, ptr.NewRequest().TakeChannel(), loop.dispatcher()));
  zx_status_t status = -1;
  ASSERT_EQ(ZX_OK, ptr->Close(&status));
  ASSERT_EQ(ZX_ERR_UNAVAILABLE, status);
}

}  // namespace
