1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_CHANGE_HANDLER_H_
6#define CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_CHANGE_HANDLER_H_
7
8#include <map>
9#include <set>
10#include <string>
11#include <utility>
12
13#include "base/files/file_path.h"
14#include "base/stl_util.h"
15#include "base/time/time.h"
16#include "chrome/browser/sync_file_system/file_change.h"
17#include "webkit/browser/fileapi/file_system_url.h"
18
19namespace sync_file_system {
20
21// Manages pending remote file changes.
22class RemoteChangeHandler {
23 public:
24  struct RemoteChange {
25    int64 changestamp;
26    std::string resource_id;
27    std::string md5_checksum;
28    base::Time updated_time;
29    fileapi::FileSystemURL url;
30    FileChange change;
31
32    RemoteChange();
33    RemoteChange(int64 changestamp,
34                 const std::string& resource_id,
35                 const std::string& md5_checksum,
36                 const base::Time& updated_time,
37                 const fileapi::FileSystemURL& url,
38                 const FileChange& change);
39    ~RemoteChange();
40  };
41
42  struct RemoteChangeComparator {
43    bool operator()(const RemoteChange& left, const RemoteChange& right);
44  };
45
46  RemoteChangeHandler();
47  virtual ~RemoteChangeHandler();
48
49  // Pushes the next change into |remote_change| and returns true.
50  bool GetChange(RemoteChange* remote_change);
51
52  // Pushes the change for the |url| into |remote_change| and returns true.
53  bool GetChangeForURL(const fileapi::FileSystemURL& url,
54                       RemoteChange* remote_change);
55
56  // Appends |remote_change| into the change queue. |remote_change| overrides an
57  // existing change for the same URL if exists.
58  void AppendChange(const RemoteChange& remote_change);
59
60  // Removes a change for the |url|.
61  bool RemoveChangeForURL(const fileapi::FileSystemURL& url);
62
63  // Removes changes for the |origin|.
64  void RemoveChangesForOrigin(const GURL& origin);
65
66  bool HasChangesForOrigin(const GURL& origin) const;
67  bool HasChanges() const { return !changes_.empty(); }
68  size_t ChangesSize() const { return changes_.size(); }
69
70 private:
71  struct ChangeQueueItem {
72    int64 changestamp;
73    fileapi::FileSystemURL url;
74
75    ChangeQueueItem();
76    ChangeQueueItem(int64 changestamp,
77                    const fileapi::FileSystemURL& url);
78  };
79
80  struct ChangeQueueComparator {
81    bool operator()(const ChangeQueueItem& left, const ChangeQueueItem& right);
82  };
83
84  typedef std::set<ChangeQueueItem, ChangeQueueComparator> PendingChangeQueue;
85
86  struct ChangeMapItem {
87    RemoteChange remote_change;
88    PendingChangeQueue::iterator position_in_queue;
89
90    ChangeMapItem();
91    ChangeMapItem(const RemoteChange& remote_change,
92                  PendingChangeQueue::iterator position_in_queue);
93    ~ChangeMapItem();
94  };
95
96  // TODO(tzik): Consider using std::pair<base::FilePath, FileType> as the key
97  // below to support directories and custom conflict handling.
98  typedef std::map<base::FilePath::StringType, ChangeMapItem> PathToChangeMap;
99  typedef std::map<GURL, PathToChangeMap> OriginToChangesMap;
100
101  PendingChangeQueue changes_;
102  OriginToChangesMap origin_to_changes_map_;
103
104  DISALLOW_COPY_AND_ASSIGN(RemoteChangeHandler);
105};
106
107}  // namespace sync_file_system
108
109#endif  // CHROME_BROWSER_SYNC_FILE_SYSTEM_DRIVE_BACKEND_REMOTE_CHANGE_HANDLER_H_
110