// Copyright (c) 2013, 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.

#include "bin/file.h"

#include "bin/builtin.h"
#include "bin/dartutils.h"
#include "bin/embedded_dart_io.h"
#include "bin/io_buffer.h"
#include "bin/utils.h"
#include "include/dart_api.h"
#include "include/dart_tools_api.h"
#include "platform/globals.h"

namespace dart {
namespace bin {

static const int kFileNativeFieldIndex = 0;

// The file pointer has been passed into Dart as an intptr_t and it is safe
// to pull it out of Dart as a 64-bit integer, cast it to an intptr_t and
// from there to a File pointer.
static File* GetFile(Dart_NativeArguments args) {
  File* file;
  Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
  ASSERT(Dart_IsInstance(dart_this));
  ThrowIfError(Dart_GetNativeInstanceField(dart_this, kFileNativeFieldIndex,
                                           reinterpret_cast<intptr_t*>(&file)));
  return file;
}

static void SetFile(Dart_Handle dart_this, intptr_t file_pointer) {
  Dart_Handle result = Dart_SetNativeInstanceField(
      dart_this, kFileNativeFieldIndex, file_pointer);
  if (Dart_IsError(result)) {
    Log::PrintErr("SetNativeInstanceField in SetFile() failed\n");
    Dart_PropagateError(result);
  }
}

void FUNCTION_NAME(File_GetPointer)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  // If the file is already closed, GetFile() will return NULL.
  if (file != NULL) {
    // Increment file's reference count. File_GetPointer() should only be called
    // when we are about to send the File* to the IO Service.
    file->Retain();
  }
  intptr_t file_pointer = reinterpret_cast<intptr_t>(file);
  Dart_SetReturnValue(args, Dart_NewInteger(file_pointer));
}

static void ReleaseFile(void* isolate_callback_data,
                        Dart_WeakPersistentHandle handle,
                        void* peer) {
  File* file = reinterpret_cast<File*>(peer);
  file->Release();
}

void FUNCTION_NAME(File_SetPointer)(Dart_NativeArguments args) {
  Dart_Handle dart_this = ThrowIfError(Dart_GetNativeArgument(args, 0));
  intptr_t file_pointer =
      DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 1));
  File* file = reinterpret_cast<File*>(file_pointer);
  Dart_WeakPersistentHandle handle = Dart_NewWeakPersistentHandle(
      dart_this, reinterpret_cast<void*>(file), sizeof(*file), ReleaseFile);
  file->SetWeakHandle(handle);
  SetFile(dart_this, file_pointer);
}

void FUNCTION_NAME(File_Open)(Dart_NativeArguments args) {
  const char* filename =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  int64_t mode = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 1));
  File::DartFileOpenMode dart_file_mode =
      static_cast<File::DartFileOpenMode>(mode);
  File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
  // Check that the file exists before opening it only for
  // reading. This is to prevent the opening of directories as
  // files. Directories can be opened for reading using the posix
  // 'open' call.
  File* file = File::Open(filename, file_mode);
  if (file != NULL) {
    Dart_SetReturnValue(args,
                        Dart_NewInteger(reinterpret_cast<intptr_t>(file)));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Exists)(Dart_NativeArguments args) {
  const char* filename =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  bool exists = File::Exists(filename);
  Dart_SetReturnValue(args, Dart_NewBoolean(exists));
}

void FUNCTION_NAME(File_Close)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  file->Close();
  file->DeleteWeakHandle(Dart_CurrentIsolate());
  file->Release();

  // NULL-out the now potentially dangling pointer.
  Dart_Handle dart_this = Dart_GetNativeArgument(args, 0);
  SetFile(dart_this, 0);
  Dart_SetReturnValue(args, Dart_NewInteger(0));
}

void FUNCTION_NAME(File_ReadByte)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  uint8_t buffer;
  int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1);
  if (bytes_read == 1) {
    Dart_SetReturnValue(args, Dart_NewInteger(buffer));
  } else if (bytes_read == 0) {
    Dart_SetReturnValue(args, Dart_NewInteger(-1));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_WriteByte)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  int64_t byte = 0;
  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &byte)) {
    uint8_t buffer = static_cast<uint8_t>(byte & 0xff);
    bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1);
    if (success) {
      Dart_SetReturnValue(args, Dart_NewInteger(1));
    } else {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    }
  } else {
    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
  }
}

void FUNCTION_NAME(File_Read)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  Dart_Handle length_object = Dart_GetNativeArgument(args, 1);
  int64_t length = 0;
  if (DartUtils::GetInt64Value(length_object, &length)) {
    uint8_t* buffer = NULL;
    Dart_Handle external_array = IOBuffer::Allocate(length, &buffer);
    int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length);
    if (bytes_read < 0) {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    } else {
      if (bytes_read < length) {
        const int kNumArgs = 3;
        Dart_Handle dart_args[kNumArgs];
        dart_args[0] = external_array;
        dart_args[1] = Dart_NewInteger(0);
        dart_args[2] = Dart_NewInteger(bytes_read);
        // TODO(sgjesse): Cache the _makeUint8ListView function somewhere.
        Dart_Handle io_lib =
            Dart_LookupLibrary(DartUtils::NewString("dart:io"));
        if (Dart_IsError(io_lib)) {
          Dart_PropagateError(io_lib);
        }
        Dart_Handle array_view =
            Dart_Invoke(io_lib, DartUtils::NewString("_makeUint8ListView"),
                        kNumArgs, dart_args);
        Dart_SetReturnValue(args, array_view);
      } else {
        Dart_SetReturnValue(args, external_array);
      }
    }
  } else {
    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
  }
}

void FUNCTION_NAME(File_ReadInto)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);
  ASSERT(Dart_IsList(buffer_obj));
  // start and end arguments are checked in Dart code to be
  // integers and have the property that end <=
  // list.length. Therefore, it is safe to extract their value as
  // intptr_t.
  intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
  intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));
  intptr_t length = end - start;
  intptr_t array_len = 0;
  Dart_Handle result = Dart_ListLength(buffer_obj, &array_len);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }
  ASSERT(end <= array_len);
  uint8_t* buffer = Dart_ScopeAllocate(length);
  int64_t bytes_read = file->Read(reinterpret_cast<void*>(buffer), length);
  if (bytes_read >= 0) {
    result = Dart_ListSetAsBytes(buffer_obj, start, buffer, bytes_read);
    if (Dart_IsError(result)) {
      Dart_SetReturnValue(args, result);
    } else {
      Dart_SetReturnValue(args, Dart_NewInteger(bytes_read));
    }
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_WriteFrom)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);

  Dart_Handle buffer_obj = Dart_GetNativeArgument(args, 1);

  // Offset and length arguments are checked in Dart code to be
  // integers and have the property that (offset + length) <=
  // list.length. Therefore, it is safe to extract their value as
  // intptr_t.
  intptr_t start = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 2));
  intptr_t end = DartUtils::GetIntptrValue(Dart_GetNativeArgument(args, 3));

  // The buffer object passed in has to be an Int8List or Uint8List object.
  // Acquire a direct pointer to the data area of the buffer object.
  Dart_TypedData_Type type;
  intptr_t length = end - start;
  intptr_t buffer_len = 0;
  void* buffer = NULL;
  Dart_Handle result =
      Dart_TypedDataAcquireData(buffer_obj, &type, &buffer, &buffer_len);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }

  ASSERT(type == Dart_TypedData_kUint8 || type == Dart_TypedData_kInt8);
  ASSERT(end <= buffer_len);
  ASSERT(buffer != NULL);

  // Write all the data out into the file.
  char* byte_buffer = reinterpret_cast<char*>(buffer);
  bool success = file->WriteFully(byte_buffer + start, length);

  // Release the direct pointer acquired above.
  result = Dart_TypedDataReleaseData(buffer_obj);
  if (Dart_IsError(result)) {
    Dart_PropagateError(result);
  }

  if (!success) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  } else {
    Dart_SetReturnValue(args, Dart_Null());
  }
}

void FUNCTION_NAME(File_Position)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  intptr_t return_value = file->Position();
  if (return_value >= 0) {
    Dart_SetReturnValue(args, Dart_NewInteger(return_value));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_SetPosition)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  int64_t position = 0;
  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &position)) {
    if (file->SetPosition(position)) {
      Dart_SetReturnValue(args, Dart_True());
    } else {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    }
  } else {
    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
  }
}

void FUNCTION_NAME(File_Truncate)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  int64_t length = 0;
  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &length)) {
    if (file->Truncate(length)) {
      Dart_SetReturnValue(args, Dart_True());
    } else {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    }
  } else {
    OSError os_error(-1, "Invalid argument", OSError::kUnknown);
    Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
  }
}

void FUNCTION_NAME(File_Length)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  int64_t return_value = file->Length();
  if (return_value >= 0) {
    Dart_SetReturnValue(args, Dart_NewInteger(return_value));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_LengthFromPath)(Dart_NativeArguments args) {
  const char* path = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  int64_t return_value = File::LengthFromPath(path);
  if (return_value >= 0) {
    Dart_SetReturnValue(args, Dart_NewInteger(return_value));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_LastModified)(Dart_NativeArguments args) {
  const char* name = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  int64_t return_value = File::LastModified(name);
  if (return_value >= 0) {
    Dart_SetReturnValue(args,
                        Dart_NewInteger(return_value * kMillisecondsPerSecond));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_SetLastModified)(Dart_NativeArguments args) {
  const char* name = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  int64_t millis;
  if (!DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &millis)) {
    Dart_ThrowException(DartUtils::NewDartArgumentError(
        "The second argument must be a 64-bit int."));
  }
  if (!File::SetLastModified(name, millis)) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_LastAccessed)(Dart_NativeArguments args) {
  const char* name = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  int64_t return_value = File::LastAccessed(name);
  if (return_value >= 0) {
    Dart_SetReturnValue(args,
                        Dart_NewInteger(return_value * kMillisecondsPerSecond));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_SetLastAccessed)(Dart_NativeArguments args) {
  const char* name = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  int64_t millis;
  if (!DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &millis)) {
    Dart_ThrowException(DartUtils::NewDartArgumentError(
        "The second argument must be a 64-bit int."));
  }
  if (!File::SetLastAccessed(name, millis)) {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Flush)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  if (file->Flush()) {
    Dart_SetReturnValue(args, Dart_True());
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Lock)(Dart_NativeArguments args) {
  File* file = GetFile(args);
  ASSERT(file != NULL);
  int64_t lock;
  int64_t start;
  int64_t end;
  if (DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 1), &lock) &&
      DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 2), &start) &&
      DartUtils::GetInt64Value(Dart_GetNativeArgument(args, 3), &end)) {
    if ((lock >= File::kLockMin) && (lock <= File::kLockMax) && (start >= 0) &&
        (end == -1 || end > start)) {
      if (file->Lock(static_cast<File::LockType>(lock), start, end)) {
        Dart_SetReturnValue(args, Dart_True());
      } else {
        Dart_SetReturnValue(args, DartUtils::NewDartOSError());
      }
      return;
    }
  }
  OSError os_error(-1, "Invalid argument", OSError::kUnknown);
  Dart_SetReturnValue(args, DartUtils::NewDartOSError(&os_error));
}

void FUNCTION_NAME(File_Create)(Dart_NativeArguments args) {
  const char* str = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  bool result = File::Create(str);
  if (result) {
    Dart_SetReturnValue(args, Dart_NewBoolean(result));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_CreateLink)(Dart_NativeArguments args) {
  if (Dart_IsString(Dart_GetNativeArgument(args, 0)) &&
      Dart_IsString(Dart_GetNativeArgument(args, 1))) {
    const char* name =
        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
    const char* target =
        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
    if (!File::CreateLink(name, target)) {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    }
  } else {
    Dart_Handle err =
        DartUtils::NewDartArgumentError("Non-string argument to Link.create");
    Dart_SetReturnValue(args, err);
  }
}

void FUNCTION_NAME(File_LinkTarget)(Dart_NativeArguments args) {
  if (Dart_IsString(Dart_GetNativeArgument(args, 0))) {
    const char* name =
        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
    const char* target = File::LinkTarget(name);
    if (target == NULL) {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    } else {
      Dart_SetReturnValue(args, DartUtils::NewString(target));
    }
  } else {
    Dart_Handle err =
        DartUtils::NewDartArgumentError("Non-string argument to Link.target");
    Dart_SetReturnValue(args, err);
  }
}

void FUNCTION_NAME(File_Delete)(Dart_NativeArguments args) {
  const char* str = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  bool result = File::Delete(str);
  if (result) {
    Dart_SetReturnValue(args, Dart_NewBoolean(result));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_DeleteLink)(Dart_NativeArguments args) {
  const char* str = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  bool result = File::DeleteLink(str);
  if (result) {
    Dart_SetReturnValue(args, Dart_NewBoolean(result));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Rename)(Dart_NativeArguments args) {
  const char* old_path =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  const char* new_path =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
  bool result = File::Rename(old_path, new_path);
  if (result) {
    Dart_SetReturnValue(args, Dart_NewBoolean(result));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_RenameLink)(Dart_NativeArguments args) {
  const char* old_path =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  const char* new_path =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
  bool result = File::RenameLink(old_path, new_path);
  if (result) {
    Dart_SetReturnValue(args, Dart_NewBoolean(result));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_Copy)(Dart_NativeArguments args) {
  const char* old_path =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  const char* new_path =
      DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
  bool result = File::Copy(old_path, new_path);
  if (result) {
    Dart_SetReturnValue(args, Dart_NewBoolean(result));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_ResolveSymbolicLinks)(Dart_NativeArguments args) {
  const char* str = DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
  const char* path = File::GetCanonicalPath(str);
  if (path != NULL) {
    Dart_SetReturnValue(args, DartUtils::NewString(path));
  } else {
    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
  }
}

void FUNCTION_NAME(File_OpenStdio)(Dart_NativeArguments args) {
  int64_t fd = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 0));
  ASSERT((fd == STDIN_FILENO) || (fd == STDOUT_FILENO) ||
         (fd == STDERR_FILENO));
  File* file = File::OpenStdio(static_cast<int>(fd));
  Dart_SetReturnValue(args, Dart_NewInteger(reinterpret_cast<intptr_t>(file)));
}

void FUNCTION_NAME(File_GetStdioHandleType)(Dart_NativeArguments args) {
  int64_t fd = DartUtils::GetIntegerValue(Dart_GetNativeArgument(args, 0));
  ASSERT((fd == STDIN_FILENO) || (fd == STDOUT_FILENO) ||
         (fd == STDERR_FILENO));
  File::StdioHandleType type = File::GetStdioHandleType(static_cast<int>(fd));
  Dart_SetReturnValue(args, Dart_NewInteger(type));
}

void FUNCTION_NAME(File_GetType)(Dart_NativeArguments args) {
  if (Dart_IsString(Dart_GetNativeArgument(args, 0)) &&
      Dart_IsBoolean(Dart_GetNativeArgument(args, 1))) {
    const char* str =
        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
    bool follow_links =
        DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1));
    File::Type type = File::GetType(str, follow_links);
    Dart_SetReturnValue(args, Dart_NewInteger(static_cast<int>(type)));
  } else {
    Dart_Handle err = DartUtils::NewDartArgumentError(
        "Non-string argument to FileSystemEntity.type");
    Dart_SetReturnValue(args, err);
  }
}

void FUNCTION_NAME(File_Stat)(Dart_NativeArguments args) {
  if (Dart_IsString(Dart_GetNativeArgument(args, 0))) {
    const char* path =
        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));

    int64_t stat_data[File::kStatSize];
    File::Stat(path, stat_data);
    if (stat_data[File::kType] == File::kDoesNotExist) {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    } else {
      Dart_Handle returned_data =
          Dart_NewTypedData(Dart_TypedData_kInt64, File::kStatSize);
      if (Dart_IsError(returned_data)) {
        Dart_PropagateError(returned_data);
      }
      Dart_TypedData_Type data_type_unused;
      void* data_location;
      intptr_t data_length_unused;
      Dart_Handle status =
          Dart_TypedDataAcquireData(returned_data, &data_type_unused,
                                    &data_location, &data_length_unused);
      if (Dart_IsError(status)) {
        Dart_PropagateError(status);
      }
      memmove(data_location, stat_data, File::kStatSize * sizeof(int64_t));
      status = Dart_TypedDataReleaseData(returned_data);
      if (Dart_IsError(status)) {
        Dart_PropagateError(status);
      }
      Dart_SetReturnValue(args, returned_data);
    }
  } else {
    Dart_Handle err = DartUtils::NewDartArgumentError(
        "Non-string argument to FileSystemEntity.stat");
    Dart_SetReturnValue(args, err);
  }
}

void FUNCTION_NAME(File_AreIdentical)(Dart_NativeArguments args) {
  if (Dart_IsString(Dart_GetNativeArgument(args, 0)) &&
      Dart_IsString(Dart_GetNativeArgument(args, 1))) {
    const char* path_1 =
        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 0));
    const char* path_2 =
        DartUtils::GetStringValue(Dart_GetNativeArgument(args, 1));
    File::Identical result = File::AreIdentical(path_1, path_2);
    if (result == File::kError) {
      Dart_SetReturnValue(args, DartUtils::NewDartOSError());
    } else {
      Dart_SetReturnValue(args, Dart_NewBoolean(result == File::kIdentical));
    }
  } else {
    Dart_Handle err = DartUtils::NewDartArgumentError(
        "Non-string argument to FileSystemEntity.identical");
    Dart_SetReturnValue(args, err);
  }
}

static int64_t CObjectInt32OrInt64ToInt64(CObject* cobject) {
  ASSERT(cobject->IsInt32OrInt64());
  int64_t result;
  if (cobject->IsInt32()) {
    CObjectInt32 value(cobject);
    result = value.Value();
  } else {
    CObjectInt64 value(cobject);
    result = value.Value();
  }
  return result;
}

File* CObjectToFilePointer(CObject* cobject) {
  CObjectIntptr value(cobject);
  return reinterpret_cast<File*>(value.Value());
}

CObject* File::ExistsRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    CObjectString filename(request[0]);
    bool result = File::Exists(filename.CString());
    return CObject::Bool(result);
  }
  return CObject::IllegalArgumentError();
}

CObject* File::CreateRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    CObjectString filename(request[0]);
    bool result = File::Create(filename.CString());
    if (result) {
      return CObject::True();
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::OpenRequest(const CObjectArray& request) {
  File* file = NULL;
  if ((request.Length() == 2) && request[0]->IsString() &&
      request[1]->IsInt32()) {
    CObjectString filename(request[0]);
    CObjectInt32 mode(request[1]);
    File::DartFileOpenMode dart_file_mode =
        static_cast<File::DartFileOpenMode>(mode.Value());
    File::FileOpenMode file_mode = File::DartModeToFileMode(dart_file_mode);
    file = File::Open(filename.CString(), file_mode);
    if (file != NULL) {
      return new CObjectIntptr(
          CObject::NewIntptr(reinterpret_cast<intptr_t>(file)));
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::DeleteRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    CObjectString filename(request[0]);
    bool result = File::Delete(filename.CString());
    if (result) {
      return CObject::True();
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::False();
}

CObject* File::RenameRequest(const CObjectArray& request) {
  if ((request.Length() == 2) && request[0]->IsString() &&
      request[1]->IsString()) {
    CObjectString old_path(request[0]);
    CObjectString new_path(request[1]);
    bool completed = File::Rename(old_path.CString(), new_path.CString());
    if (completed) {
      return CObject::True();
    }
    return CObject::NewOSError();
  }
  return CObject::IllegalArgumentError();
}

CObject* File::CopyRequest(const CObjectArray& request) {
  if ((request.Length() == 2) && request[0]->IsString() &&
      request[1]->IsString()) {
    CObjectString old_path(request[0]);
    CObjectString new_path(request[1]);
    bool completed = File::Copy(old_path.CString(), new_path.CString());
    if (completed) {
      return CObject::True();
    }
    return CObject::NewOSError();
  }
  return CObject::IllegalArgumentError();
}

CObject* File::ResolveSymbolicLinksRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    CObjectString filename(request[0]);
    const char* result = File::GetCanonicalPath(filename.CString());
    if (result != NULL) {
      CObject* path = new CObjectString(CObject::NewString(result));
      return path;
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::CloseRequest(const CObjectArray& request) {
  intptr_t return_value = -1;
  if ((request.Length() == 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    return_value = 0;
    // We have retained a reference to the file here. Therefore the file's
    // destructor can't be running. Since no further requests are dispatched by
    // the Dart code after an async close call, this Close() can't be racing
    // with any other call on the file. We don't do an extra Release(), and we
    // don't delete the weak persistent handle. The file is closed here, but the
    // memory will be cleaned up when the finalizer runs.
    ASSERT(!file->IsClosed());
    file->Close();
  }
  return new CObjectIntptr(CObject::NewIntptr(return_value));
}

CObject* File::PositionRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if (!file->IsClosed()) {
      intptr_t return_value = file->Position();
      if (return_value >= 0) {
        return new CObjectIntptr(CObject::NewIntptr(return_value));
      } else {
        return CObject::NewOSError();
      }
    } else {
      return CObject::FileClosedError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::SetPositionRequest(const CObjectArray& request) {
  if ((request.Length() >= 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if ((request.Length() == 2) && request[1]->IsInt32OrInt64()) {
      if (!file->IsClosed()) {
        int64_t position = CObjectInt32OrInt64ToInt64(request[1]);
        if (file->SetPosition(position)) {
          return CObject::True();
        } else {
          return CObject::NewOSError();
        }
      } else {
        return CObject::FileClosedError();
      }
    } else {
      return CObject::IllegalArgumentError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::TruncateRequest(const CObjectArray& request) {
  if ((request.Length() >= 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if ((request.Length() == 2) && request[1]->IsInt32OrInt64()) {
      if (!file->IsClosed()) {
        int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
        if (file->Truncate(length)) {
          return CObject::True();
        } else {
          return CObject::NewOSError();
        }
      } else {
        return CObject::FileClosedError();
      }
    } else {
      return CObject::IllegalArgumentError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::LengthRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if (!file->IsClosed()) {
      int64_t return_value = file->Length();
      if (return_value >= 0) {
        return new CObjectInt64(CObject::NewInt64(return_value));
      } else {
        return CObject::NewOSError();
      }
    } else {
      return CObject::FileClosedError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::LengthFromPathRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    CObjectString filepath(request[0]);
    int64_t return_value = File::LengthFromPath(filepath.CString());
    if (return_value >= 0) {
      return new CObjectInt64(CObject::NewInt64(return_value));
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::LastAccessedRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    CObjectString filepath(request[0]);
    int64_t return_value = File::LastAccessed(filepath.CString());
    if (return_value >= 0) {
      return new CObjectIntptr(
          CObject::NewInt64(return_value * kMillisecondsPerSecond));
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::SetLastAccessedRequest(const CObjectArray& request) {
  if ((request.Length() == 2) && request[0]->IsString() &&
      request[1]->IsInt32OrInt64()) {
    CObjectString filepath(request[0]);
    const int64_t millis = CObjectInt32OrInt64ToInt64(request[1]);
    if (File::SetLastAccessed(filepath.CString(), millis)) {
      return CObject::Null();
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::LastModifiedRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    CObjectString filepath(request[0]);
    int64_t return_value = File::LastModified(filepath.CString());
    if (return_value >= 0) {
      return new CObjectIntptr(
          CObject::NewInt64(return_value * kMillisecondsPerSecond));
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::SetLastModifiedRequest(const CObjectArray& request) {
  if ((request.Length() == 2) && request[0]->IsString() &&
      request[1]->IsInt32OrInt64()) {
    CObjectString filepath(request[0]);
    const int64_t millis = CObjectInt32OrInt64ToInt64(request[1]);
    if (File::SetLastModified(filepath.CString(), millis)) {
      return CObject::Null();
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::FlushRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if (!file->IsClosed()) {
      if (file->Flush()) {
        return CObject::True();
      } else {
        return CObject::NewOSError();
      }
    } else {
      return CObject::FileClosedError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::ReadByteRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if (!file->IsClosed()) {
      uint8_t buffer;
      int64_t bytes_read = file->Read(reinterpret_cast<void*>(&buffer), 1);
      if (bytes_read > 0) {
        return new CObjectIntptr(CObject::NewIntptr(buffer));
      } else if (bytes_read == 0) {
        return new CObjectIntptr(CObject::NewIntptr(-1));
      } else {
        return CObject::NewOSError();
      }
    } else {
      return CObject::FileClosedError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::WriteByteRequest(const CObjectArray& request) {
  if ((request.Length() >= 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if ((request.Length() == 2) && request[1]->IsInt32OrInt64()) {
      if (!file->IsClosed()) {
        int64_t byte = CObjectInt32OrInt64ToInt64(request[1]);
        uint8_t buffer = static_cast<uint8_t>(byte & 0xff);
        bool success = file->WriteFully(reinterpret_cast<void*>(&buffer), 1);
        if (success) {
          return new CObjectInt64(CObject::NewInt64(1));
        } else {
          return CObject::NewOSError();
        }
      } else {
        return CObject::FileClosedError();
      }
    } else {
      return CObject::IllegalArgumentError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::ReadRequest(const CObjectArray& request) {
  if ((request.Length() >= 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if ((request.Length() == 2) && request[1]->IsInt32OrInt64()) {
      if (!file->IsClosed()) {
        int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
        Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
        ASSERT(io_buffer != NULL);
        uint8_t* data = io_buffer->value.as_external_typed_data.data;
        int64_t bytes_read = file->Read(data, length);
        if (bytes_read >= 0) {
          CObjectExternalUint8Array* external_array =
              new CObjectExternalUint8Array(io_buffer);
          external_array->SetLength(bytes_read);
          CObjectArray* result = new CObjectArray(CObject::NewArray(2));
          result->SetAt(0, new CObjectIntptr(CObject::NewInt32(0)));
          result->SetAt(1, external_array);
          return result;
        } else {
          CObject::FreeIOBufferData(io_buffer);
          return CObject::NewOSError();
        }
      } else {
        return CObject::FileClosedError();
      }
    } else {
      return CObject::IllegalArgumentError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::ReadIntoRequest(const CObjectArray& request) {
  if ((request.Length() >= 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if ((request.Length() == 2) && request[1]->IsInt32OrInt64()) {
      if (!file->IsClosed()) {
        int64_t length = CObjectInt32OrInt64ToInt64(request[1]);
        Dart_CObject* io_buffer = CObject::NewIOBuffer(length);
        ASSERT(io_buffer != NULL);
        uint8_t* data = io_buffer->value.as_external_typed_data.data;
        int64_t bytes_read = file->Read(data, length);
        if (bytes_read >= 0) {
          CObjectExternalUint8Array* external_array =
              new CObjectExternalUint8Array(io_buffer);
          external_array->SetLength(bytes_read);
          CObjectArray* result = new CObjectArray(CObject::NewArray(3));
          result->SetAt(0, new CObjectIntptr(CObject::NewInt32(0)));
          result->SetAt(1, new CObjectInt64(CObject::NewInt64(bytes_read)));
          result->SetAt(2, external_array);
          return result;
        } else {
          CObject::FreeIOBufferData(io_buffer);
          return CObject::NewOSError();
        }
      } else {
        return CObject::FileClosedError();
      }
    } else {
      return CObject::IllegalArgumentError();
    }
  }
  return CObject::IllegalArgumentError();
}

static int SizeInBytes(Dart_TypedData_Type type) {
  switch (type) {
    case Dart_TypedData_kInt8:
    case Dart_TypedData_kUint8:
    case Dart_TypedData_kUint8Clamped:
      return 1;
    case Dart_TypedData_kInt16:
    case Dart_TypedData_kUint16:
      return 2;
    case Dart_TypedData_kInt32:
    case Dart_TypedData_kUint32:
    case Dart_TypedData_kFloat32:
      return 4;
    case Dart_TypedData_kInt64:
    case Dart_TypedData_kUint64:
    case Dart_TypedData_kFloat64:
      return 8;
    default:
      break;
  }
  UNREACHABLE();
  return -1;
}

CObject* File::WriteFromRequest(const CObjectArray& request) {
  if ((request.Length() >= 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if ((request.Length() == 4) &&
        (request[1]->IsTypedData() || request[1]->IsArray()) &&
        request[2]->IsInt32OrInt64() && request[3]->IsInt32OrInt64()) {
      if (!file->IsClosed()) {
        int64_t start = CObjectInt32OrInt64ToInt64(request[2]);
        int64_t end = CObjectInt32OrInt64ToInt64(request[3]);
        int64_t length = end - start;
        uint8_t* buffer_start;
        if (request[1]->IsTypedData()) {
          CObjectTypedData typed_data(request[1]);
          start = start * SizeInBytes(typed_data.Type());
          length = length * SizeInBytes(typed_data.Type());
          buffer_start = typed_data.Buffer() + start;
        } else {
          CObjectArray array(request[1]);
          buffer_start = Dart_ScopeAllocate(length);
          for (int i = 0; i < length; i++) {
            if (array[i + start]->IsInt32OrInt64()) {
              int64_t value = CObjectInt32OrInt64ToInt64(array[i + start]);
              buffer_start[i] = static_cast<uint8_t>(value & 0xFF);
            } else {
              // Unsupported type.
              return CObject::IllegalArgumentError();
            }
          }
          start = 0;
        }
        bool success =
            file->WriteFully(reinterpret_cast<void*>(buffer_start), length);
        if (success) {
          return new CObjectInt64(CObject::NewInt64(length));
        } else {
          return CObject::NewOSError();
        }
      } else {
        return CObject::FileClosedError();
      }
    } else {
      return CObject::IllegalArgumentError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::CreateLinkRequest(const CObjectArray& request) {
  if ((request.Length() != 2) || !request[0]->IsString() ||
      !request[1]->IsString()) {
    return CObject::IllegalArgumentError();
  }
  CObjectString link_name(request[0]);
  CObjectString target_name(request[1]);
  if (File::CreateLink(link_name.CString(), target_name.CString())) {
    return CObject::True();
  } else {
    return CObject::NewOSError();
  }
}

CObject* File::DeleteLinkRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    CObjectString link_path(request[0]);
    bool result = File::DeleteLink(link_path.CString());
    if (result) {
      return CObject::True();
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::RenameLinkRequest(const CObjectArray& request) {
  if ((request.Length() == 2) && request[0]->IsString() &&
      request[1]->IsString()) {
    CObjectString old_path(request[0]);
    CObjectString new_path(request[1]);
    bool completed = File::RenameLink(old_path.CString(), new_path.CString());
    if (completed) {
      return CObject::True();
    }
    return CObject::NewOSError();
  }
  return CObject::IllegalArgumentError();
}

CObject* File::LinkTargetRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    CObjectString link_path(request[0]);
    const char* target = File::LinkTarget(link_path.CString());
    if (target != NULL) {
      CObject* result = new CObjectString(CObject::NewString(target));
      return result;
    } else {
      return CObject::NewOSError();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::TypeRequest(const CObjectArray& request) {
  if ((request.Length() == 2) && request[0]->IsString() &&
      request[1]->IsBool()) {
    CObjectString path(request[0]);
    CObjectBool follow_links(request[1]);
    File::Type type = File::GetType(path.CString(), follow_links.Value());
    return new CObjectInt32(CObject::NewInt32(type));
  }
  return CObject::IllegalArgumentError();
}

CObject* File::IdenticalRequest(const CObjectArray& request) {
  if ((request.Length() == 2) && request[0]->IsString() &&
      request[1]->IsString()) {
    CObjectString path1(request[0]);
    CObjectString path2(request[1]);
    File::Identical result =
        File::AreIdentical(path1.CString(), path2.CString());
    if (result == File::kError) {
      return CObject::NewOSError();
    } else if (result == File::kIdentical) {
      return CObject::True();
    } else {
      return CObject::False();
    }
  }
  return CObject::IllegalArgumentError();
}

CObject* File::StatRequest(const CObjectArray& request) {
  if ((request.Length() == 1) && request[0]->IsString()) {
    int64_t data[File::kStatSize];
    CObjectString path(request[0]);
    File::Stat(path.CString(), data);
    if (data[File::kType] == File::kDoesNotExist) {
      return CObject::NewOSError();
    }
    CObjectArray* result = new CObjectArray(CObject::NewArray(File::kStatSize));
    for (int i = 0; i < File::kStatSize; ++i) {
      result->SetAt(i, new CObjectInt64(CObject::NewInt64(data[i])));
    }
    CObjectArray* wrapper = new CObjectArray(CObject::NewArray(2));
    wrapper->SetAt(0, new CObjectInt32(CObject::NewInt32(CObject::kSuccess)));
    wrapper->SetAt(1, result);
    return wrapper;
  }
  return CObject::IllegalArgumentError();
}

CObject* File::LockRequest(const CObjectArray& request) {
  if ((request.Length() >= 1) && request[0]->IsIntptr()) {
    File* file = CObjectToFilePointer(request[0]);
    RefCntReleaseScope<File> rs(file);
    if ((request.Length() == 4) && request[1]->IsInt32OrInt64() &&
        request[2]->IsInt32OrInt64() && request[3]->IsInt32OrInt64()) {
      if (!file->IsClosed()) {
        int64_t lock = CObjectInt32OrInt64ToInt64(request[1]);
        int64_t start = CObjectInt32OrInt64ToInt64(request[2]);
        int64_t end = CObjectInt32OrInt64ToInt64(request[3]);
        if (file->Lock(static_cast<File::LockType>(lock), start, end)) {
          return CObject::True();
        } else {
          return CObject::NewOSError();
        }
      } else {
        return CObject::FileClosedError();
      }
    } else {
      return CObject::IllegalArgumentError();
    }
  }
  return CObject::IllegalArgumentError();
}

}  // namespace bin
}  // namespace dart
