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

#include <vector>

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/stl_util.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/browser/sync_file_system/local/canned_syncable_file_system.h"
#include "chrome/browser/sync_file_system/local/local_file_sync_context.h"
#include "chrome/browser/sync_file_system/local/local_file_sync_service.h"
#include "chrome/browser/sync_file_system/local/mock_sync_status_observer.h"
#include "chrome/browser/sync_file_system/local/sync_file_system_backend.h"
#include "chrome/browser/sync_file_system/mock_remote_file_sync_service.h"
#include "chrome/browser/sync_file_system/sync_callbacks.h"
#include "chrome/browser/sync_file_system/sync_event_observer.h"
#include "chrome/browser/sync_file_system/sync_file_metadata.h"
#include "chrome/browser/sync_file_system/sync_file_system_service.h"
#include "chrome/browser/sync_file_system/sync_file_system_test_util.h"
#include "chrome/browser/sync_file_system/sync_status_code.h"
#include "chrome/browser/sync_file_system/syncable_file_system_util.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/browser/fileapi/file_system_context.h"

using content::BrowserThread;
using fileapi::FileSystemURL;
using fileapi::FileSystemURLSet;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using ::testing::InSequence;
using ::testing::InvokeWithoutArgs;
using ::testing::Return;
using ::testing::StrictMock;
using ::testing::_;

namespace sync_file_system {

namespace {

const char kOrigin[] = "http://example.com";

template <typename R> struct AssignTrait {
  typedef const R& ArgumentType;
};

template <> struct AssignTrait<SyncFileStatus> {
  typedef SyncFileStatus ArgumentType;
};

template <typename R>
void AssignValueAndQuit(base::RunLoop* run_loop,
                        SyncStatusCode* status_out, R* value_out,
                        SyncStatusCode status,
                        typename AssignTrait<R>::ArgumentType value) {
  DCHECK(status_out);
  DCHECK(value_out);
  DCHECK(run_loop);
  *status_out = status;
  *value_out = value;
  run_loop->Quit();
}

// This is called on IO thread.
void VerifyFileError(base::RunLoop* run_loop,
                     base::PlatformFileError error) {
  DCHECK(run_loop);
  EXPECT_EQ(base::PLATFORM_FILE_OK, error);
  run_loop->Quit();
}

}  // namespace

class MockSyncEventObserver : public SyncEventObserver {
 public:
  MockSyncEventObserver() {}
  virtual ~MockSyncEventObserver() {}

  MOCK_METHOD3(OnSyncStateUpdated,
               void(const GURL& app_origin,
                    SyncServiceState state,
                    const std::string& description));
  MOCK_METHOD4(OnFileSynced,
               void(const fileapi::FileSystemURL& url,
                    SyncFileStatus status,
                    SyncAction action,
                    SyncDirection direction));
};

ACTION_P3(NotifyStateAndCallback,
          mock_remote_service, service_state, operation_status) {
  mock_remote_service->NotifyRemoteServiceStateUpdated(
      service_state, "Test event.");
  base::MessageLoopProxy::current()->PostTask(
      FROM_HERE, base::Bind(arg1, operation_status));
}

ACTION_P(RecordState, states) {
  states->push_back(arg1);
}

ACTION_P(MockStatusCallback, status) {
  base::MessageLoopProxy::current()->PostTask(
      FROM_HERE, base::Bind(arg4, status));
}

ACTION_P2(MockSyncFileCallback, status, url) {
  base::MessageLoopProxy::current()->PostTask(
      FROM_HERE, base::Bind(arg0, status, url));
}

class SyncFileSystemServiceTest : public testing::Test {
 protected:
  SyncFileSystemServiceTest()
      : thread_bundle_(content::TestBrowserThreadBundle::REAL_FILE_THREAD |
                       content::TestBrowserThreadBundle::REAL_IO_THREAD) {}

  virtual void SetUp() OVERRIDE {
    file_system_.reset(new CannedSyncableFileSystem(
        GURL(kOrigin),
        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO),
        BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)));

    local_service_ = new LocalFileSyncService(&profile_);
    remote_service_ = new StrictMock<MockRemoteFileSyncService>;
    sync_service_.reset(new SyncFileSystemService(&profile_));

    EXPECT_CALL(*mock_remote_service(),
                AddServiceObserver(sync_service_.get())).Times(1);
    EXPECT_CALL(*mock_remote_service(),
                AddFileStatusObserver(sync_service_.get())).Times(1);
    EXPECT_CALL(*mock_remote_service(),
                GetLocalChangeProcessor())
        .WillOnce(Return(&local_change_processor_));
    EXPECT_CALL(*mock_remote_service(),
                SetRemoteChangeProcessor(local_service_)).Times(1);

    sync_service_->Initialize(
        make_scoped_ptr(local_service_),
        scoped_ptr<RemoteFileSyncService>(remote_service_));

    // Disable auto sync by default.
    EXPECT_CALL(*mock_remote_service(), SetSyncEnabled(false)).Times(1);
    sync_service_->SetSyncEnabledForTesting(false);

    file_system_->SetUp();
  }

  virtual void TearDown() OVERRIDE {
    sync_service_->Shutdown();
    file_system_->TearDown();
    RevokeSyncableFileSystem();
    content::RunAllPendingInMessageLoop(BrowserThread::FILE);
  }

  void InitializeApp() {
    base::RunLoop run_loop;
    SyncStatusCode status = SYNC_STATUS_UNKNOWN;

    EXPECT_CALL(*mock_remote_service(),
                RegisterOriginForTrackingChanges(GURL(kOrigin), _)).Times(1);

    sync_service_->InitializeForApp(
        file_system_->file_system_context(),
        GURL(kOrigin),
        AssignAndQuitCallback(&run_loop, &status));
    run_loop.Run();

    EXPECT_EQ(SYNC_STATUS_OK, status);
    EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->OpenFileSystem());
  }

  // Calls InitializeForApp after setting up the mock remote service to
  // perform following when RegisterOriginForTrackingChanges is called:
  //  1. Notify RemoteFileSyncService's observers of |state_to_notify|
  //  2. Run the given callback with |status_to_return|.
  //
  // ..and verifies if following conditions are met:
  //  1. The SyncEventObserver of the service is called with
  //     |expected_states| service state values.
  //  2. InitializeForApp's callback is called with |expected_status|
  //  3. GetCurrentState() is called at least |expected_current_state_calls|
  //     times (which means that the sync service tried to start sync).
  void InitializeAppForObserverTest(
      RemoteServiceState state_to_notify,
      SyncStatusCode status_to_return,
      const std::vector<SyncServiceState>& expected_states,
      SyncStatusCode expected_status) {
    StrictMock<MockSyncEventObserver> event_observer;
    sync_service_->AddSyncEventObserver(&event_observer);

    EnableSync();

    EXPECT_CALL(*mock_remote_service(),
                RegisterOriginForTrackingChanges(GURL(kOrigin), _))
        .WillOnce(NotifyStateAndCallback(mock_remote_service(),
                                         state_to_notify,
                                         status_to_return));

    std::vector<SyncServiceState> actual_states;
    EXPECT_CALL(event_observer, OnSyncStateUpdated(GURL(), _, _))
        .WillRepeatedly(RecordState(&actual_states));

    SyncStatusCode actual_status = SYNC_STATUS_UNKNOWN;
    base::RunLoop run_loop;
    sync_service_->InitializeForApp(
        file_system_->file_system_context(),
        GURL(kOrigin),
        AssignAndQuitCallback(&run_loop, &actual_status));
    run_loop.Run();

    EXPECT_EQ(expected_status, actual_status);
    ASSERT_EQ(expected_states.size(), actual_states.size());
    for (size_t i = 0; i < actual_states.size(); ++i)
      EXPECT_EQ(expected_states[i], actual_states[i]);
  }

  FileSystemURL URL(const std::string& path) const {
    return file_system_->URL(path);
  }

  StrictMock<MockRemoteFileSyncService>* mock_remote_service() {
    return remote_service_;
  }

  StrictMock<MockLocalChangeProcessor>* mock_local_change_processor() {
    return &local_change_processor_;
  }

  void EnableSync() {
    EXPECT_CALL(*mock_remote_service(), SetSyncEnabled(true)).Times(1);
    sync_service_->SetSyncEnabledForTesting(true);
  }

  ScopedEnableSyncFSDirectoryOperation enable_directory_operation_;

  content::TestBrowserThreadBundle thread_bundle_;
  TestingProfile profile_;
  scoped_ptr<CannedSyncableFileSystem> file_system_;

  // Their ownerships are transferred to SyncFileSystemService.
  LocalFileSyncService* local_service_;
  StrictMock<MockRemoteFileSyncService>* remote_service_;
  StrictMock<MockLocalChangeProcessor> local_change_processor_;

  scoped_ptr<SyncFileSystemService> sync_service_;
};

TEST_F(SyncFileSystemServiceTest, InitializeForApp) {
  InitializeApp();
}

TEST_F(SyncFileSystemServiceTest, InitializeForAppSuccess) {
  std::vector<SyncServiceState> expected_states;
  expected_states.push_back(SYNC_SERVICE_RUNNING);

  InitializeAppForObserverTest(
      REMOTE_SERVICE_OK,
      SYNC_STATUS_OK,
      expected_states,
      SYNC_STATUS_OK);
}

TEST_F(SyncFileSystemServiceTest, InitializeForAppWithNetworkFailure) {
  std::vector<SyncServiceState> expected_states;
  expected_states.push_back(SYNC_SERVICE_TEMPORARY_UNAVAILABLE);

  // Notify REMOTE_SERVICE_TEMPORARY_UNAVAILABLE and callback with
  // SYNC_STATUS_NETWORK_ERROR.  This should let the
  // InitializeApp fail.
  InitializeAppForObserverTest(
      REMOTE_SERVICE_TEMPORARY_UNAVAILABLE,
      SYNC_STATUS_NETWORK_ERROR,
      expected_states,
      SYNC_STATUS_NETWORK_ERROR);
}

TEST_F(SyncFileSystemServiceTest, InitializeForAppWithError) {
  std::vector<SyncServiceState> expected_states;
  expected_states.push_back(SYNC_SERVICE_DISABLED);

  // Notify REMOTE_SERVICE_DISABLED and callback with
  // SYNC_STATUS_FAILED.  This should let the InitializeApp fail.
  InitializeAppForObserverTest(
      REMOTE_SERVICE_DISABLED,
      SYNC_STATUS_FAILED,
      expected_states,
      SYNC_STATUS_FAILED);
}

// Flaky.  http://crbug.com/237710
TEST_F(SyncFileSystemServiceTest, DISABLED_SimpleLocalSyncFlow) {
  InitializeApp();

  StrictMock<MockSyncStatusObserver> status_observer;

  EnableSync();
  file_system_->backend()->sync_context()->
      set_mock_notify_changes_duration_in_sec(0);
  file_system_->AddSyncStatusObserver(&status_observer);

  // We'll test one local sync for this file.
  const FileSystemURL kFile(file_system_->URL("foo"));

  base::RunLoop run_loop;

  // We should get called OnSyncEnabled and OnWriteEnabled on kFile.
  // (We quit the run loop when OnWriteEnabled is called on kFile)
  EXPECT_CALL(status_observer, OnSyncEnabled(kFile))
      .Times(AtLeast(1));
  EXPECT_CALL(status_observer, OnWriteEnabled(kFile))
      .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

  // We expect a set of method calls for starting a local sync.
  EXPECT_CALL(*mock_remote_service(), GetCurrentState())
      .Times(AtLeast(2))
      .WillRepeatedly(Return(REMOTE_SERVICE_OK));

  // The local_change_processor's ApplyLocalChange should be called once
  // with ADD_OR_UPDATE change for TYPE_FILE.
  const FileChange change(FileChange::FILE_CHANGE_ADD_OR_UPDATE,
                          SYNC_FILE_TYPE_FILE);
  EXPECT_CALL(*mock_local_change_processor(),
              ApplyLocalChange(change, _, _, kFile, _))
      .WillOnce(MockStatusCallback(SYNC_STATUS_OK));

  EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kFile));

  run_loop.Run();
}

TEST_F(SyncFileSystemServiceTest, SimpleRemoteSyncFlow) {
  InitializeApp();

  EnableSync();

  base::RunLoop run_loop;

  // We expect a set of method calls for starting a remote sync.
  EXPECT_CALL(*mock_remote_service(), GetCurrentState())
      .Times(AtLeast(1))
      .WillRepeatedly(Return(REMOTE_SERVICE_OK));
  EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_))
      .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));

  // This should trigger a remote sync.
  mock_remote_service()->NotifyRemoteChangeQueueUpdated(1);

  run_loop.Run();
}

TEST_F(SyncFileSystemServiceTest, SimpleSyncFlowWithFileBusy) {
  InitializeApp();

  EnableSync();
  file_system_->backend()->sync_context()->
      set_mock_notify_changes_duration_in_sec(0);

  const FileSystemURL kFile(file_system_->URL("foo"));

  base::RunLoop run_loop;

  // We expect a set of method calls for starting a remote sync.
  EXPECT_CALL(*mock_remote_service(), GetCurrentState())
      .Times(AtLeast(3))
      .WillRepeatedly(Return(REMOTE_SERVICE_OK));

  {
    InSequence sequence;

    // Return with SYNC_STATUS_FILE_BUSY once.
    EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_))
        .WillOnce(MockSyncFileCallback(SYNC_STATUS_FILE_BUSY,
                                       kFile));

    // ProcessRemoteChange should be called again when the becomes
    // not busy.
    EXPECT_CALL(*mock_remote_service(), ProcessRemoteChange(_))
        .WillOnce(InvokeWithoutArgs(&run_loop, &base::RunLoop::Quit));
  }

  // We might also see an activity for local sync as we're going to make
  // a local write operation on kFile.
  EXPECT_CALL(*mock_local_change_processor(),
              ApplyLocalChange(_, _, _, kFile, _))
      .Times(AnyNumber());

  // This should trigger a remote sync.
  mock_remote_service()->NotifyRemoteChangeQueueUpdated(1);

  // Start a local operation on the same file (to make it BUSY).
  base::RunLoop verify_file_error_run_loop;
  BrowserThread::PostTask(
      BrowserThread::IO,
      FROM_HERE,
      base::Bind(&CannedSyncableFileSystem::DoCreateFile,
                 base::Unretained(file_system_.get()),
                 kFile, base::Bind(&VerifyFileError,
                                   &verify_file_error_run_loop)));

  run_loop.Run();

  mock_remote_service()->NotifyRemoteChangeQueueUpdated(0);

  verify_file_error_run_loop.Run();
}

TEST_F(SyncFileSystemServiceTest, GetFileSyncStatus) {
  InitializeApp();

  const FileSystemURL kFile(file_system_->URL("foo"));

  SyncStatusCode status;
  SyncFileStatus sync_file_status;

  // 1. The file is not in conflicting nor in pending change state.
  {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile))
        .WillOnce(Return(false));

    status = SYNC_STATUS_UNKNOWN;
    sync_file_status = SYNC_FILE_STATUS_UNKNOWN;
    sync_service_->GetFileSyncStatus(
        kFile,
        base::Bind(&AssignValueAndQuit<SyncFileStatus>,
                   &run_loop, &status, &sync_file_status));
    run_loop.Run();

    EXPECT_EQ(SYNC_STATUS_OK, status);
    EXPECT_EQ(SYNC_FILE_STATUS_SYNCED, sync_file_status);
  }

  // 2. Conflicting case.
  {
    base::RunLoop run_loop;
    EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile))
        .WillOnce(Return(true));

    status = SYNC_STATUS_UNKNOWN;
    sync_file_status = SYNC_FILE_STATUS_UNKNOWN;
    sync_service_->GetFileSyncStatus(
        kFile,
        base::Bind(&AssignValueAndQuit<SyncFileStatus>,
                   &run_loop, &status, &sync_file_status));
    run_loop.Run();

    EXPECT_EQ(SYNC_STATUS_OK, status);
    EXPECT_EQ(SYNC_FILE_STATUS_CONFLICTING, sync_file_status);
  }

  // 3. The file has pending local changes.
  {
    EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->CreateFile(kFile));

    base::RunLoop run_loop;
    EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile))
        .WillOnce(Return(false));

    status = SYNC_STATUS_UNKNOWN;
    sync_file_status = SYNC_FILE_STATUS_UNKNOWN;
    sync_service_->GetFileSyncStatus(
        kFile,
        base::Bind(&AssignValueAndQuit<SyncFileStatus>,
                   &run_loop, &status, &sync_file_status));
    run_loop.Run();

    EXPECT_EQ(SYNC_STATUS_OK, status);
    EXPECT_EQ(SYNC_FILE_STATUS_HAS_PENDING_CHANGES, sync_file_status);
  }

  // 4. The file has a conflict and pending local changes. In this case
  // we return SYNC_FILE_STATUS_CONFLICTING.
  {
    EXPECT_EQ(base::PLATFORM_FILE_OK, file_system_->TruncateFile(kFile, 1U));

    base::RunLoop run_loop;
    EXPECT_CALL(*mock_remote_service(), IsConflicting(kFile))
        .WillOnce(Return(true));

    status = SYNC_STATUS_UNKNOWN;
    sync_file_status = SYNC_FILE_STATUS_UNKNOWN;
    sync_service_->GetFileSyncStatus(
        kFile,
        base::Bind(&AssignValueAndQuit<SyncFileStatus>,
                   &run_loop, &status, &sync_file_status));
    run_loop.Run();

    EXPECT_EQ(SYNC_STATUS_OK, status);
    EXPECT_EQ(SYNC_FILE_STATUS_CONFLICTING, sync_file_status);
  }
}

}  // namespace sync_file_system
