// 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.

#ifndef STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_CONTEXT_H_
#define STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_CONTEXT_H_

#include <stdint.h>

#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/supports_user_data.h"
#include "base/threading/thread_checker.h"
#include "storage/browser/fileapi/task_runner_bound_observer_list.h"
#include "storage/browser/storage_browser_export.h"
#include "storage/common/quota/quota_limit_type.h"

namespace base {
class SequencedTaskRunner;
}

namespace storage {

class FileSystemContext;

// A context class which is carried around by FileSystemOperation and
// its delegated tasks. It is valid to reuse one context instance across
// multiple operations as far as those operations are supposed to share
// the same context (e.g. use the same task runner, share the quota etc).
// Note that the remaining quota bytes (allowed_bytes_growth) may be
// updated during the execution of write operations.
class STORAGE_EXPORT FileSystemOperationContext
    : public base::SupportsUserData {
 public:
  explicit FileSystemOperationContext(FileSystemContext* context);

  // Specifies |task_runner| which the operation is performed on.
  // The backend of |task_runner| must outlive the IO thread.
  FileSystemOperationContext(FileSystemContext* context,
                             base::SequencedTaskRunner* task_runner);

  ~FileSystemOperationContext() override;

  FileSystemContext* file_system_context() const {
    return file_system_context_.get();
  }

  // Updates the current remaining quota.
  // This can be called to update the remaining quota during the operation.
  void set_allowed_bytes_growth(const int64_t& allowed_bytes_growth) {
    allowed_bytes_growth_ = allowed_bytes_growth;
  }

  // Returns the current remaining quota.
  int64_t allowed_bytes_growth() const { return allowed_bytes_growth_; }
  storage::QuotaLimitType quota_limit_type() const { return quota_limit_type_; }
  base::SequencedTaskRunner* task_runner() const { return task_runner_.get(); }

  ChangeObserverList* change_observers() { return &change_observers_; }
  UpdateObserverList* update_observers() { return &update_observers_; }

  // Following setters should be called only on the same thread as the
  // FileSystemOperationContext is created (i.e. are not supposed be updated
  // after the context's passed onto other task runners).
  void set_change_observers(const ChangeObserverList& list) {
    DCHECK(setter_thread_checker_.CalledOnValidThread());
    change_observers_ = list;
  }
  void set_update_observers(const UpdateObserverList& list) {
    DCHECK(setter_thread_checker_.CalledOnValidThread());
    update_observers_ = list;
  }
  void set_quota_limit_type(storage::QuotaLimitType limit_type) {
    DCHECK(setter_thread_checker_.CalledOnValidThread());
    quota_limit_type_ = limit_type;
  }

 private:
  scoped_refptr<FileSystemContext> file_system_context_;
  scoped_refptr<base::SequencedTaskRunner> task_runner_;

  // The current remaining quota, used by ObfuscatedFileUtil.
  int64_t allowed_bytes_growth_;

  // The current quota limit type, used by ObfuscatedFileUtil.
  storage::QuotaLimitType quota_limit_type_;

  // Observers attached to this context.
  ChangeObserverList change_observers_;
  UpdateObserverList update_observers_;

  // Used to check its setters are not called on arbitrary thread.
  base::ThreadChecker setter_thread_checker_;

  DISALLOW_COPY_AND_ASSIGN(FileSystemOperationContext);
};

}  // namespace storage

#endif  // STORAGE_BROWSER_FILEAPI_FILE_SYSTEM_OPERATION_CONTEXT_H_
