// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#ifndef BIN_DIRECTORY_H_
#define BIN_DIRECTORY_H_

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "platform/globals.h"
#include "platform/thread.h"


namespace dart {
namespace bin {

enum ListType {
  kListFile = 0,
  kListDirectory = 1,
  kListLink = 2,
  kListError = 3,
  kListDone = 4
};

class PathBuffer {
 public:
  PathBuffer();
  ~PathBuffer() {
    free(data_);
  }

  bool Add(const char* name);
  bool AddW(const wchar_t* name);

  char* AsString() const;
  wchar_t* AsStringW() const;

  void Reset(int new_length);

  int length() const {
    return length_;
  }

 private:
  void* data_;
  int length_;

  DISALLOW_COPY_AND_ASSIGN(PathBuffer);
};

class DirectoryListing;

struct LinkList;

// DirectoryListingEntry is used as a stack item, when performing recursive
// directory listing. By using DirectoryListingEntry as stack elements, a
// directory listing can be paused e.g. when a buffer is full, and resumed
// later on.
//
// The stack is managed by the DirectoryListing's PathBuffer. Each
// DirectoryListingEntry stored a entry-length, that it'll reset the PathBuffer
// to on each call to Next.
class DirectoryListingEntry {
 public:
  explicit DirectoryListingEntry(DirectoryListingEntry* parent)
    : parent_(parent), lister_(0), done_(false), link_(NULL) {}

  ~DirectoryListingEntry() {
    ResetLink();
  }

  ListType Next(DirectoryListing* listing);

  DirectoryListingEntry* parent() const {
    return parent_;
  }

  LinkList* link() {
    return link_;
  }

  void set_link(LinkList* link) {
    link_ = link;
  }

  void ResetLink();

 private:
  DirectoryListingEntry* parent_;
  intptr_t lister_;
  bool done_;
  int path_length_;
  LinkList* link_;

  DISALLOW_COPY_AND_ASSIGN(DirectoryListingEntry);
};

class DirectoryListing {
 public:
  DirectoryListing(const char* dir_name, bool recursive, bool follow_links)
    : top_(NULL),
      error_(false),
      recursive_(recursive),
      follow_links_(follow_links) {
    if (!path_buffer_.Add(dir_name)) {
      error_ = true;
    }
    Push(new DirectoryListingEntry(NULL));
  }

  virtual ~DirectoryListing() {
    while (!IsEmpty()) {
      Pop();
    }
  }

  virtual bool HandleDirectory(char* dir_name) = 0;
  virtual bool HandleFile(char* file_name) = 0;
  virtual bool HandleLink(char* link_name) = 0;
  virtual bool HandleError(const char* dir_name) = 0;
  virtual void HandleDone() {}

  void Push(DirectoryListingEntry* directory) {
    top_ = directory;
  }

  void Pop() {
    ASSERT(!IsEmpty());
    DirectoryListingEntry* current = top_;
    top_ = top_->parent();
    delete current;
  }

  bool IsEmpty() const {
    return top_ == NULL;
  }

  DirectoryListingEntry* top() const {
    return top_;
  }

  bool recursive() const {
    return recursive_;
  }

  bool follow_links() const {
    return follow_links_;
  }

  char* CurrentPath() {
    return path_buffer_.AsString();
  }

  PathBuffer& path_buffer() {
    return path_buffer_;
  }

  bool error() const {
    return error_;
  }

 private:
  PathBuffer path_buffer_;
  DirectoryListingEntry* top_;
  bool error_;
  bool recursive_;
  bool follow_links_;
};


class AsyncDirectoryListing : public DirectoryListing {
 public:
  enum Response {
    kListFile = 0,
    kListDirectory = 1,
    kListLink = 2,
    kListError = 3,
    kListDone = 4
  };

  AsyncDirectoryListing(const char* dir_name,
                        bool recursive,
                        bool follow_links)
      : DirectoryListing(dir_name, recursive, follow_links) {}

  virtual ~AsyncDirectoryListing() {}
  virtual bool HandleDirectory(char* dir_name);
  virtual bool HandleFile(char* file_name);
  virtual bool HandleLink(char* file_name);
  virtual bool HandleError(const char* dir_name);
  virtual void HandleDone();

  void SetArray(CObjectArray* array, intptr_t length) {
    ASSERT(length % 2 == 0);
    array_ = array;
    index_ = 0;
    length_ = length;
  }

  intptr_t index() const {
    return index_;
  }

 private:
  bool AddFileSystemEntityToResponse(Response response, char* arg);
  CObjectArray* array_;
  intptr_t index_;
  intptr_t length_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(AsyncDirectoryListing);
};


class SyncDirectoryListing: public DirectoryListing {
 public:
  SyncDirectoryListing(Dart_Handle results,
                       const char* dir_name,
                       bool recursive,
                       bool follow_links)
      : DirectoryListing(dir_name, recursive, follow_links),
        results_(results) {
    add_string_ = DartUtils::NewString("add");
    directory_type_ =
        DartUtils::GetDartType(DartUtils::kIOLibURL, "Directory");
    file_type_ =
        DartUtils::GetDartType(DartUtils::kIOLibURL, "File");
    link_type_ =
        DartUtils::GetDartType(DartUtils::kIOLibURL, "Link");
  }
  virtual ~SyncDirectoryListing() {}
  virtual bool HandleDirectory(char* dir_name);
  virtual bool HandleFile(char* file_name);
  virtual bool HandleLink(char* file_name);
  virtual bool HandleError(const char* dir_name);

 private:
  Dart_Handle results_;
  Dart_Handle add_string_;
  Dart_Handle directory_type_;
  Dart_Handle file_type_;
  Dart_Handle link_type_;

  DISALLOW_IMPLICIT_CONSTRUCTORS(SyncDirectoryListing);
};


class Directory {
 public:
  enum ExistsResult {
    UNKNOWN,
    EXISTS,
    DOES_NOT_EXIST
  };

  static void List(DirectoryListing* listing);
  static ExistsResult Exists(const char* path);
  static char* Current();
  static bool SetCurrent(const char* path);
  static bool Create(const char* path);
  static char* CreateTemp(const char* const_template, bool system);
  static bool Delete(const char* path, bool recursive);
  static bool Rename(const char* path, const char* new_path);

  static CObject* CreateRequest(const CObjectArray& request);
  static CObject* DeleteRequest(const CObjectArray& request);
  static CObject* ExistsRequest(const CObjectArray& request);
  static CObject* CreateTempRequest(const CObjectArray& request);
  static CObject* CreateSystemTempRequest(const CObjectArray& request);
  static CObject* ListStartRequest(const CObjectArray& request);
  static CObject* ListNextRequest(const CObjectArray& request);
  static CObject* ListStopRequest(const CObjectArray& request);
  static CObject* RenameRequest(const CObjectArray& request);

 private:
  DISALLOW_ALLOCATION();
  DISALLOW_IMPLICIT_CONSTRUCTORS(Directory);
};

}  // namespace bin
}  // namespace dart

#endif  // BIN_DIRECTORY_H_
