// 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 "chrome/browser/history/android/sqlite_cursor.h"

#include <jni.h>

#include "base/android/jni_android.h"
#include "base/android/jni_array.h"
#include "base/android/jni_string.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "chrome/browser/bookmarks/bookmark_test_helpers.h"
#include "chrome/browser/history/android/android_history_provider_service.h"
#include "chrome/browser/history/android/android_history_types.h"
#include "chrome/browser/history/android/android_time.h"
#include "chrome/browser/history/history_service.h"
#include "chrome/browser/history/history_service_factory.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/test/test_browser_thread.h"
#include "content/public/test/test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace {

using base::Bind;
using base::Time;
using content::BrowserThread;
using history::AndroidStatement;
using history::HistoryAndBookmarkRow;
using history::SearchRow;

// The test cases in this file don't test the JNI interface which will be
// covered in Java tests.
class SQLiteCursorTest : public testing::Test,
                         public SQLiteCursor::TestObserver {
 public:
  SQLiteCursorTest()
      : profile_manager_(
          TestingBrowserProcess::GetGlobal()),
        ui_thread_(BrowserThread::UI, &message_loop_),
        file_thread_(BrowserThread::FILE, &message_loop_) {
  }
  virtual ~SQLiteCursorTest() {
  }

 protected:
  virtual void SetUp() OVERRIDE {
    // Setup the testing profile, so the bookmark_model_sql_handler could
    // get the bookmark model from it.
    ASSERT_TRUE(profile_manager_.SetUp());
    // It seems that the name has to be chrome::kInitialProfile, so it
    // could be found by ProfileManager::GetLastUsedProfile().
    testing_profile_ = profile_manager_.CreateTestingProfile(
        chrome::kInitialProfile);

    testing_profile_->CreateBookmarkModel(true);
    test::WaitForBookmarkModelToLoad(testing_profile_);

    testing_profile_->CreateFaviconService();
    ASSERT_TRUE(testing_profile_->CreateHistoryService(true, false));
    service_.reset(new AndroidHistoryProviderService(testing_profile_));
    hs_ = HistoryServiceFactory::GetForProfile(testing_profile_,
                                               Profile::EXPLICIT_ACCESS);
  }

  virtual void TearDown() OVERRIDE {
    testing_profile_->DestroyHistoryService();
    profile_manager_.DeleteTestingProfile(chrome::kInitialProfile);
    testing_profile_ = NULL;
  }

  // Override SQLiteCursor::TestObserver.
  virtual void OnPostMoveToTask() OVERRIDE {
    base::MessageLoop::current()->Run();
  }

  virtual void OnGetMoveToResult() OVERRIDE {
    base::MessageLoop::current()->Quit();
  }

  virtual void OnPostGetFaviconTask() OVERRIDE {
    base::MessageLoop::current()->Run();
  }

  virtual void OnGetFaviconResult() OVERRIDE {
    base::MessageLoop::current()->Quit();
  }

 protected:
  TestingProfileManager profile_manager_;
  base::MessageLoop message_loop_;
  content::TestBrowserThread ui_thread_;
  content::TestBrowserThread file_thread_;
  scoped_ptr<AndroidHistoryProviderService> service_;
  CancelableRequestConsumer cancelable_consumer_;
  TestingProfile* testing_profile_;
  HistoryService* hs_;


 private:
  DISALLOW_COPY_AND_ASSIGN(SQLiteCursorTest);
};

class CallbackHelper : public base::RefCountedThreadSafe<CallbackHelper> {
 public:
  CallbackHelper()
      : success_(false),
        statement_(NULL) {
  }

  bool success() const {
    return success_;
  }

  AndroidStatement* statement() const {
    return statement_;
  }

  void OnInserted(AndroidHistoryProviderService::Handle handle,
                  bool success,
                  int64 id) {
    success_ = success;
    base::MessageLoop::current()->Quit();
  }

  void OnQueryResult(AndroidHistoryProviderService::Handle handle,
                     bool success,
                     AndroidStatement* statement) {
    success_ = success;
    statement_ = statement;
    base::MessageLoop::current()->Quit();
  }

 private:
  friend class base::RefCountedThreadSafe<CallbackHelper>;
  ~CallbackHelper() {
  }

  bool success_;
  AndroidStatement* statement_;

  DISALLOW_COPY_AND_ASSIGN(CallbackHelper);
};

}  // namespace

TEST_F(SQLiteCursorTest, Run) {
  HistoryAndBookmarkRow row;
  row.set_raw_url("http://www.google.com/");
  row.set_url(GURL("http://www.google.com/"));
  std::vector<unsigned char> favicon_data;
  favicon_data.push_back(1);
  base::RefCountedBytes *data_bytes =
      base::RefCountedBytes::TakeVector(&favicon_data);
  row.set_favicon(data_bytes);
  row.set_last_visit_time(Time::Now());
  row.set_visit_count(2);
  row.set_title(UTF8ToUTF16("cnn"));
  scoped_refptr<CallbackHelper> callback(new CallbackHelper());

  // Insert a row and verify it succeeded.
  service_->InsertHistoryAndBookmark(row, &cancelable_consumer_,
      Bind(&CallbackHelper::OnInserted, callback.get()));

  base::MessageLoop::current()->Run();
  EXPECT_TRUE(callback->success());

  std::vector<HistoryAndBookmarkRow::ColumnID> projections;
  projections.push_back(HistoryAndBookmarkRow::URL);
  projections.push_back(HistoryAndBookmarkRow::LAST_VISIT_TIME);
  projections.push_back(HistoryAndBookmarkRow::VISIT_COUNT);
  projections.push_back(HistoryAndBookmarkRow::FAVICON);

  // Query the inserted row.
  service_->QueryHistoryAndBookmarks(projections, std::string(),
      std::vector<base::string16>(), std::string(), &cancelable_consumer_,
      Bind(&CallbackHelper::OnQueryResult, callback.get()));
  base::MessageLoop::current()->Run();
  ASSERT_TRUE(callback->success());

  AndroidStatement* statement = callback->statement();
  std::vector<std::string> column_names;
  column_names.push_back(
      HistoryAndBookmarkRow::GetAndroidName(HistoryAndBookmarkRow::URL));
  column_names.push_back(HistoryAndBookmarkRow::GetAndroidName(
      HistoryAndBookmarkRow::LAST_VISIT_TIME));
  column_names.push_back(HistoryAndBookmarkRow::GetAndroidName(
      HistoryAndBookmarkRow::VISIT_COUNT));
  column_names.push_back(HistoryAndBookmarkRow::GetAndroidName(
      HistoryAndBookmarkRow::FAVICON));

  FaviconService* favicon_service = new FaviconService(testing_profile_);

  SQLiteCursor* cursor = new SQLiteCursor(column_names, statement,
      service_.get(), favicon_service);
  cursor->set_test_observer(this);
  JNIEnv* env = base::android::AttachCurrentThread();
  EXPECT_EQ(1, cursor->GetCount(env, NULL));
  EXPECT_EQ(0, cursor->MoveTo(env, NULL, 0));
  EXPECT_EQ(row.url().spec(), base::android::ConvertJavaStringToUTF8(
      cursor->GetString(env, NULL, 0)).c_str());
  EXPECT_EQ(history::ToDatabaseTime(row.last_visit_time()),
      cursor->GetLong(env, NULL, 1));
  EXPECT_EQ(row.visit_count(), cursor->GetInt(env, NULL, 2));
  base::android::ScopedJavaLocalRef<jbyteArray> data =
      cursor->GetBlob(env, NULL, 3);
  std::vector<uint8> out;
  base::android::JavaByteArrayToByteVector(env, data.obj(), &out);
  EXPECT_EQ(data_bytes->data().size(), out.size());
  EXPECT_EQ(data_bytes->data()[0], out[0]);
  cursor->Destroy(env, NULL);
  // Cursor::Destroy posts the task in UI thread, run Message loop to release
  // the statement, delete SQLiteCursor itself etc.
  content::RunAllPendingInMessageLoop();
}
