// 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/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 "extensions/common/extension.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 {

KeyedService* 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());
}
