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

#include "list.h"
#include "os/fuchsia.h"

#include <lib/zxio/inception.h>
#include <lib/zxio/zxio.h>
#include <magma_util/dlog.h>

// Offsets must match struct os_dirent, static_asserts below.
struct os_dirent_impl {
   ino_t d_ino;
   char d_name[NAME_MAX];
};

static_assert(offsetof(struct os_dirent_impl, d_ino) == offsetof(struct os_dirent, d_ino),
              "d_ino offset mismatch");
static_assert(offsetof(struct os_dirent_impl, d_name) == offsetof(struct os_dirent, d_name),
              "d_ino offset mismatch");

class os_dir {
public:
   os_dir() { buffer = new char[buffer_size()]; }

   ~os_dir()
   {
      if (dir_init) {
         zxio_close(&io_storage.io);
      }
      delete[] buffer;
   }

   static size_t buffer_size() { return ZXIO_DIRENT_ITERATOR_DEFAULT_BUFFER_SIZE; }

   // Always consumes |dir_channel|
   bool Init(zx_handle_t dir_channel)
   {
      zx_status_t status = zxio_dir_init(&io_storage, dir_channel);
      if (status != ZX_OK) {
         DLOG("zxio_dir_init failed: %d", status);
         return false;
      }
      dir_init = true;

      status = zxio_dirent_iterator_init(&iterator, &io_storage.io, buffer, buffer_size());
      if (status != ZX_OK) {
         DLOG("zxio_dirent_iterator_init failed: %d", status);
         return false;
      }

      return true;
   }

   struct os_dirent_impl* Next()
   {
      zxio_dirent_t* dirent;
      zx_status_t status = zxio_dirent_iterator_next(&iterator, &dirent);
      if (status != ZX_OK) {
         DLOG("zxio_dirent_iterator_next failed: %d", status);
         return nullptr;
      }

      entry.d_ino = dirent->inode;
      strncpy(entry.d_name, dirent->name, dirent->size);
      entry.d_name[dirent->size] = 0;

      return &entry;
   }

private:
   bool dir_init = false;
   zxio_storage_t io_storage;
   zxio_dirent_iterator_t iterator;
   struct os_dirent_impl entry;
   char* buffer = nullptr;
};

os_dir_t* os_opendir(const char* path)
{
   zx_handle_t dir_channel;
   if (!fuchsia_open(path, &dir_channel)) {
      DLOG("fuchsia_open(%s) failed\n", path);
      return nullptr;
   }

   auto dir = new os_dir();

   if (!dir->Init(dir_channel)) {
      delete dir;
      return nullptr;
   }

   return dir;
}

int os_closedir(os_dir_t* dir)
{
   // Assume param is valid.
   delete dir;
   return 0;
}

struct os_dirent* os_readdir(os_dir_t* dir) { return reinterpret_cast<os_dirent*>(dir->Next()); }
