// 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 "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/download/download_item_model.h"
#include "chrome/browser/download/download_service.h"
#include "chrome/browser/download/download_service_factory.h"
#include "chrome/browser/download/test_download_shelf.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/mock_download_item.h"
#include "content/public/test/mock_download_manager.h"
#include "content/public/test/test_browser_thread.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using ::testing::Return;
using ::testing::ReturnRefOfCopy;
using ::testing::SaveArg;
using ::testing::_;
using content::DownloadItem;

namespace {

BrowserContextKeyedService* CreateDownloadService(
    content::BrowserContext* context) {
  return new DownloadService(Profile::FromBrowserContext(context));
}

class DownloadShelfTest : public testing::Test {
 public:
  DownloadShelfTest();

 protected:
  content::MockDownloadItem* download_item() {
    return download_item_.get();
  }
  content::MockDownloadManager* download_manager() {
    return download_manager_.get();
  }
  TestDownloadShelf* shelf() {
    return &shelf_;
  }
  Profile* profile() { return profile_.get(); }

  virtual void SetUp() OVERRIDE {
    DownloadServiceFactory::GetInstance()->SetTestingFactory(
        profile(), &CreateDownloadService);
  }

  virtual void TearDown() OVERRIDE {
    DownloadServiceFactory::GetInstance()->SetTestingFactory(
        profile(), NULL);
  }

 private:
  scoped_ptr<content::MockDownloadItem> GetInProgressMockDownload();

  base::MessageLoopForUI message_loop_;
  content::TestBrowserThread ui_thread_;
  scoped_ptr<content::MockDownloadItem> download_item_;
  scoped_ptr<content::MockDownloadManager> download_manager_;
  TestDownloadShelf shelf_;
  scoped_ptr<TestingProfile> profile_;
};

DownloadShelfTest::DownloadShelfTest()
    : ui_thread_(content::BrowserThread::UI, &message_loop_),
      profile_(new TestingProfile()) {
  download_item_.reset(new ::testing::NiceMock<content::MockDownloadItem>());
  ON_CALL(*download_item_, GetAutoOpened()).WillByDefault(Return(false));
  ON_CALL(*download_item_, GetMimeType()).WillByDefault(Return("text/plain"));
  ON_CALL(*download_item_, GetOpenWhenComplete()).WillByDefault(Return(false));
  ON_CALL(*download_item_, GetTargetDisposition())
      .WillByDefault(Return(DownloadItem::TARGET_DISPOSITION_OVERWRITE));
  ON_CALL(*download_item_, GetURL())
      .WillByDefault(ReturnRefOfCopy(GURL("http://example.com/foo")));
  ON_CALL(*download_item_, GetState())
      .WillByDefault(Return(DownloadItem::IN_PROGRESS));
  ON_CALL(*download_item_, IsTemporary()).WillByDefault(Return(false));
  ON_CALL(*download_item_, ShouldOpenFileBasedOnExtension())
      .WillByDefault(Return(false));
  ON_CALL(*download_item_, GetBrowserContext())
      .WillByDefault(Return(profile()));

  download_manager_.reset(
      new ::testing::NiceMock<content::MockDownloadManager>());
  ON_CALL(*download_manager_, GetDownload(_))
      .WillByDefault(Return(download_item_.get()));
  ON_CALL(*download_manager_, GetBrowserContext())
      .WillByDefault(Return(profile()));

  shelf_.set_download_manager(download_manager_.get());
}

} // namespace

TEST_F(DownloadShelfTest, ClosesShelfWhenHidden) {
  shelf()->Show();
  EXPECT_TRUE(shelf()->IsShowing());
  shelf()->Hide();
  EXPECT_FALSE(shelf()->IsShowing());
  shelf()->Unhide();
  EXPECT_TRUE(shelf()->IsShowing());
}

TEST_F(DownloadShelfTest, CloseWhileHiddenPreventsShowOnUnhide) {
  shelf()->Show();
  shelf()->Hide();
  shelf()->Close(DownloadShelf::AUTOMATIC);
  shelf()->Unhide();
  EXPECT_FALSE(shelf()->IsShowing());
}

TEST_F(DownloadShelfTest, UnhideDoesntShowIfNotShownOnHide) {
  shelf()->Hide();
  shelf()->Unhide();
  EXPECT_FALSE(shelf()->IsShowing());
}

TEST_F(DownloadShelfTest, AddDownloadWhileHiddenUnhides) {
  shelf()->Show();
  shelf()->Hide();
  shelf()->AddDownload(download_item());
  EXPECT_TRUE(shelf()->IsShowing());
}

TEST_F(DownloadShelfTest, AddDownloadWhileHiddenUnhidesAndShows) {
  shelf()->Hide();
  shelf()->AddDownload(download_item());
  EXPECT_TRUE(shelf()->IsShowing());
}

// Normal downloads should be added synchronously and cause the shelf to show.
TEST_F(DownloadShelfTest, AddNormalDownload) {
  EXPECT_FALSE(shelf()->IsShowing());
  shelf()->AddDownload(download_item());
  EXPECT_TRUE(shelf()->did_add_download());
  EXPECT_TRUE(shelf()->IsShowing());
}

// Add a transient download. It should not be added immediately. Instead it
// should be added after a delay. For testing, the delay is set to 0 seconds. So
// the download should be added once the message loop is flushed.
TEST_F(DownloadShelfTest, AddDelayedDownload) {
  EXPECT_CALL(*download_item(), ShouldOpenFileBasedOnExtension())
      .WillRepeatedly(Return(true));
  ASSERT_TRUE(DownloadItemModel(download_item())
              .ShouldRemoveFromShelfWhenComplete());
  shelf()->AddDownload(download_item());

  EXPECT_FALSE(shelf()->did_add_download());
  EXPECT_FALSE(shelf()->IsShowing());

  base::RunLoop run_loop;
  run_loop.RunUntilIdle();

  EXPECT_TRUE(shelf()->did_add_download());
  EXPECT_TRUE(shelf()->IsShowing());
}

// Add a transient download that completes before the delay. It should not be
// displayed on the shelf.
TEST_F(DownloadShelfTest, AddDelayedCompletedDownload) {
  EXPECT_CALL(*download_item(), ShouldOpenFileBasedOnExtension())
      .WillRepeatedly(Return(true));
  ASSERT_TRUE(DownloadItemModel(download_item())
              .ShouldRemoveFromShelfWhenComplete());
  shelf()->AddDownload(download_item());

  EXPECT_FALSE(shelf()->did_add_download());
  EXPECT_FALSE(shelf()->IsShowing());

  EXPECT_CALL(*download_item(), GetState())
      .WillRepeatedly(Return(DownloadItem::COMPLETE));
  EXPECT_CALL(*download_item(), GetAutoOpened())
      .WillRepeatedly(Return(true));

  base::RunLoop run_loop;
  run_loop.RunUntilIdle();

  EXPECT_FALSE(shelf()->did_add_download());
  EXPECT_FALSE(shelf()->IsShowing());
}

// Add a transient download that completes and becomes non-transient before the
// delay. It should be displayed on the shelf even though it is complete.
TEST_F(DownloadShelfTest, AddDelayedCompleteNonTransientDownload) {
  EXPECT_CALL(*download_item(), ShouldOpenFileBasedOnExtension())
      .WillRepeatedly(Return(true));
  ASSERT_TRUE(DownloadItemModel(download_item())
              .ShouldRemoveFromShelfWhenComplete());
  shelf()->AddDownload(download_item());

  EXPECT_FALSE(shelf()->did_add_download());
  EXPECT_FALSE(shelf()->IsShowing());

  EXPECT_CALL(*download_item(), GetState())
      .WillRepeatedly(Return(DownloadItem::COMPLETE));
  EXPECT_CALL(*download_item(), ShouldOpenFileBasedOnExtension())
      .WillRepeatedly(Return(false));
  ASSERT_FALSE(DownloadItemModel(download_item())
               .ShouldRemoveFromShelfWhenComplete());

  base::RunLoop run_loop;
  run_loop.RunUntilIdle();

  EXPECT_TRUE(shelf()->did_add_download());
  EXPECT_TRUE(shelf()->IsShowing());
}
