// 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/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(&kAsyncLoopConfigAttachToThread);
  vfs::internal::DirectoryConnection connection(0, &dir);

  CallBindTwiceAndTest(&connection);
}

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

  CallBindTwiceAndTest(&connection);
}

TEST(ConnectionBindCalledTwice, NodeConnection) {
  vfs::PseudoDir dir;
  async::Loop loop(&kAsyncLoopConfigAttachToThread);
  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{};

  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(&kAsyncLoopConfigAttachToThread);
  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
