// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/network/persistent_cookie_store.h"

#include <vector>

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/stringprintf.h"
#include "base/time.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/storage/savegame.h"
#include "cobalt/storage/savegame_fake.h"
#include "cobalt/storage/storage_manager.h"
#include "googleurl/src/gurl.h"
#include "net/cookies/canonical_cookie.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace network {

namespace {

scoped_ptr<net::CanonicalCookie> CreateTestCookie() {
  GURL url("http://www.example.com/test");
  base::Time current_time = base::Time::Now();
  base::Time expiration_time = current_time + base::TimeDelta::FromDays(1);
  scoped_ptr<net::CanonicalCookie> cookie(net::CanonicalCookie::Create(
      url, "A", "2", "www.example.com", "/test", "", "", current_time,
      expiration_time, false, false));
  return cookie.Pass();
}

void DummyOnLoaded(const std::vector<net::CanonicalCookie*>& cookies) {
  UNREFERENCED_PARAMETER(cookies);
}

class CallbackWaiter {
 public:
  CallbackWaiter() : was_called_event_(true, false) {}
  virtual ~CallbackWaiter() {}
  bool TimedWait() {
    return was_called_event_.TimedWait(base::TimeDelta::FromSeconds(5));
  }

 protected:
  void Signal() { was_called_event_.Signal(); }

 private:
  base::WaitableEvent was_called_event_;

  DISALLOW_COPY_AND_ASSIGN(CallbackWaiter);
};

class FlushWaiter : public CallbackWaiter {
 public:
  FlushWaiter() {}
  void OnFlushDone() { Signal(); }

 private:
  DISALLOW_COPY_AND_ASSIGN(FlushWaiter);
};

class CookieLoader : public CallbackWaiter {
 public:
  CookieLoader() {}
  ~CookieLoader() {
    for (std::vector<net::CanonicalCookie*>::iterator it = cookies.begin();
         it != cookies.end(); ++it) {
      delete *it;
    }
  }

  void OnCookieLoad(const std::vector<net::CanonicalCookie*>& loaded_cookies) {
    cookies = loaded_cookies;
    Signal();
  }
  std::vector<net::CanonicalCookie*> cookies;

 private:
  DISALLOW_COPY_AND_ASSIGN(CookieLoader);
};

class DummyUpgradeHandler : public storage::StorageManager::UpgradeHandler {
  void OnUpgrade(storage::StorageManager* /*storage*/, const char* /*data*/,
                 int /*size*/) override {}
};

std::string GetSavePath() {
  FilePath test_path;
  CHECK(PathService::Get(paths::DIR_COBALT_TEST_OUT, &test_path));
  return test_path.Append("persistent_cookie_test.bin").value();
}

class PersistentCookieStoreTest : public ::testing::Test {
 protected:
  PersistentCookieStoreTest() : message_loop_(MessageLoop::TYPE_DEFAULT) {
    scoped_ptr<storage::StorageManager::UpgradeHandler> upgrade_handler(
        new DummyUpgradeHandler());
    storage::StorageManager::Options options;
    options.savegame_options.path_override = GetSavePath();
    options.savegame_options.delete_on_destruction = true;
    options.savegame_options.factory = &storage::SavegameFake::Create;

    storage_manager_.reset(
        new storage::StorageManager(upgrade_handler.Pass(), options));
    cookie_store_ = new PersistentCookieStore(storage_manager_.get());
  }

  ~PersistentCookieStoreTest() {
    cookie_store_ = NULL;
    storage_manager_.reset(NULL);
  }

  MessageLoop message_loop_;
  scoped_ptr<storage::StorageManager> storage_manager_;
  scoped_refptr<PersistentCookieStore> cookie_store_;
};
}  // namespace

TEST_F(PersistentCookieStoreTest, LoadGetsAddedCookies) {
  // Put a cookie into the database. Flush, then reload and make sure
  // the Loaded callback contains it.
  scoped_ptr<net::CanonicalCookie> test_cookie(CreateTestCookie());
  cookie_store_->Load(base::Bind(&DummyOnLoaded));
  cookie_store_->AddCookie(*test_cookie);
  FlushWaiter waiter;
  cookie_store_->Flush(
      base::Bind(&FlushWaiter::OnFlushDone, base::Unretained(&waiter)));
  EXPECT_EQ(true, waiter.TimedWait());

  cookie_store_ = new PersistentCookieStore(storage_manager_.get());
  CookieLoader loader;
  cookie_store_->Load(
      base::Bind(&CookieLoader::OnCookieLoad, base::Unretained(&loader)));
  message_loop_.RunUntilIdle();
  EXPECT_TRUE(loader.TimedWait());
  ASSERT_EQ(1, loader.cookies.size());
  EXPECT_TRUE(test_cookie->IsEquivalent(*loader.cookies[0]));
}
}  // namespace network
}  // namespace cobalt
