// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Use the <code>chrome.syncFileSystem</code> API to save and synchronize data
// on Google Drive. This API is NOT for accessing arbitrary user docs stored in
// Google Drive. It provides app-specific syncable storage for offline and
// caching usage so that the same data can be available across different
// clients. Read <a href="app_storage.html">Manage Data</a> for more on using
// this API.
namespace syncFileSystem {
  enum SyncAction {
    added, updated, deleted
  };

  enum ServiceStatus {
    // The sync service is being initialized (e.g. restoring data from the
    // database, checking connectivity and authenticating to the service etc).
    initializing,

    // The sync service is up and running.
    running,

    // The sync service is not synchronizing files because the remote service
    // needs to be authenticated by the user to proceed.
    authentication_required,

    // The sync service is not synchronizing files because the remote service
    // is (temporarily) unavailable due to some recoverable errors, e.g.
    // network is offline, the remote service is down or not
    // reachable etc. More details should be given by |description| parameter
    // in OnServiceInfoUpdated (which could contain service-specific details).
    temporary_unavailable,

    // The sync service is disabled and the content will never sync.
    // (E.g. this could happen when the user has no account on
    // the remote service or the sync service has had an unrecoverable
    // error.)
    disabled
  };

  enum FileStatus {
    // Not conflicting and has no pending local changes.
    synced,

    // Has one or more pending local changes that haven't been synchronized.
    pending,

    // File conflicts with remote version and must be resolved manually.
    conflicting
  };

  enum SyncDirection {
    local_to_remote, remote_to_local
  };

  enum ConflictResolutionPolicy {
    last_write_win, manual
  };

  dictionary FileInfo {
    // <code>fileEntry</code> for the target file whose status has changed.
    // Contains name and path information of synchronized file.
    // On file deletion,
    // <code>fileEntry</code> information will still be available
    // but file will no longer exist.
    [instanceOf=Entry] object fileEntry;

    // Resulting file status after $(ref:onFileStatusChanged) event.
    // The status value can be <code>'synced'</code>,
    // <code>'pending'</code> or <code>'conflicting'</code>.
    FileStatus status;

    // Sync action taken to fire $(ref:onFileStatusChanged) event.
    // The action value can be
    // <code>'added'</code>, <code>'updated'</code> or <code>'deleted'</code>.
    // Only applies if status is <code>'synced'</code>.
    SyncAction? action;

    // Sync direction for the $(ref:onFileStatusChanged) event.
    // Sync direction value can be
    // <code>'local_to_remote'</code> or <code>'remote_to_local'</code>.
    // Only applies if status is <code>'synced'</code>.
    SyncDirection? direction;
  };

  dictionary FileStatusInfo {
    // One of the Entry's originally given to getFileStatuses.
    [instanceOf=Entry] object fileEntry;

    // The status value can be <code>'synced'</code>,
    // <code>'pending'</code> or <code>'conflicting'</code>.
    FileStatus status;

    // Optional error that is only returned if there was a problem retrieving
    // the FileStatus for the given file.
    DOMString? error;
  };

  dictionary StorageInfo {
    long usageBytes;
    long quotaBytes;
  };

  dictionary ServiceInfo {
    ServiceStatus state;
    DOMString description;
  };

  // A callback type for requestFileSystem.
  callback GetFileSystemCallback =
      void ([instanceOf=DOMFileSystem] object fileSystem);

  // A callback type for getUsageAndQuota.
  callback QuotaAndUsageCallback = void (StorageInfo info);

  // Returns true if operation was successful.
  callback DeleteFileSystemCallback = void (boolean result);

  // A callback type for getFileStatus.
  callback GetFileStatusCallback = void (FileStatus status);

  // A callback type for getFileStatuses.
  callback GetFileStatusesCallback = void (FileStatusInfo[] status);

  // A callback type for getServiceStatus.
  callback GetServiceStatusCallback = void (ServiceStatus status);

  // A callback type for getConflictResolutionPolicy.
  callback GetConflictResolutionPolicyCallback =
      void (ConflictResolutionPolicy policy);

  // A generic result callback to indicate success or failure.
  callback ResultCallback = void ();

  interface Functions {
    // Returns a syncable filesystem backed by Google Drive.
    // The returned <code>DOMFileSystem</code> instance can be operated on
    // in the same way as the Temporary and Persistant file systems (see
    // <a href="http://dev.w3.org/2009/dap/file-system/file-dir-sys.html">
    // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html</a>).
    //
    // Calling this multiple times from
    // the same app will return the same handle to the same file system.
    //
    // Note this call can fail. For example, if the user is not signed in to
    // Chrome or if there is no network operation. To handle these errors it is
    // important chrome.runtime.lastError is checked in the callback.
    static void requestFileSystem(GetFileSystemCallback callback);

    // Sets the default conflict resolution policy
    // for the <code>'syncable'</code> file storage for the app.
    // By default it is set to <code>'last_write_win'</code>.
    // When conflict resolution policy is set to <code>'last_write_win'</code>
    // conflicts for existing files are automatically resolved next time
    // the file is updated.
    // |callback| can be optionally given to know if the request has
    // succeeded or not.
    static void setConflictResolutionPolicy(
        ConflictResolutionPolicy policy,
        optional ResultCallback callback);

    // Gets the current conflict resolution policy.
    static void getConflictResolutionPolicy(
        GetConflictResolutionPolicyCallback callback);

    // Returns the current usage and quota in bytes
    // for the <code>'syncable'</code> file storage for the app.
    static void getUsageAndQuota([instanceOf=DOMFileSystem] object fileSystem,
                                 QuotaAndUsageCallback callback);

    // Returns the $(ref:FileStatus) for the given <code>fileEntry</code>.
    // The status value can be <code>'synced'</code>,
    // <code>'pending'</code> or <code>'conflicting'</code>.
    // Note that <code>'conflicting'</code> state only happens when
    // the service's conflict resolution policy is set to <code>'manual'</code>.
    static void getFileStatus([instanceOf=Entry] object fileEntry,
                              GetFileStatusCallback callback);

    // Returns each $(ref:FileStatus) for the given <code>fileEntry</code> array.
    // Typically called with the result from dirReader.readEntries().
    static void getFileStatuses(object[] fileEntries,
                                GetFileStatusesCallback callback);

    // Returns the current sync backend status.
    static void getServiceStatus(GetServiceStatusCallback callback);
  };

  interface Events {
    // Fired when an error or other status change has happened in the
    // sync backend (for example, when the sync is temporarily disabled due to
    // network or authentication error).
    static void onServiceStatusChanged(ServiceInfo detail);

    // Fired when a file has been updated by the background sync service.
    static void onFileStatusChanged(FileInfo detail);
  };

};
