// Copyright 2016 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/media/webrtc/tab_desktop_media_list.h"

#include "base/command_line.h"
#include "base/files/file_util.h"
#include "base/location.h"
#include "base/message_loop/message_loop.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/scoped_testing_local_state.h"
#include "chrome/test/base/test_browser_window.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/favicon_status.h"
#include "content/public/browser/navigation_entry.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/test_browser_thread_bundle.h"
#include "content/public/test/test_renderer_host.h"
#include "content/public/test/web_contents_tester.h"
#include "testing/gmock/include/gmock/gmock.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/login/users/scoped_test_user_manager.h"
#include "chrome/browser/chromeos/settings/scoped_cros_settings_test_helper.h"
#endif  // defined(OS_CHROMEOS)

using content::WebContents;
using content::WebContentsTester;

namespace {

static const int kDefaultSourceCount = 2;
static const int kThumbnailSize = 50;

class UnittestProfileManager : public ::ProfileManagerWithoutInit {
 public:
  explicit UnittestProfileManager(const base::FilePath& user_data_dir)
      : ::ProfileManagerWithoutInit(user_data_dir) {}

 protected:
  Profile* CreateProfileHelper(const base::FilePath& file_path) override {
    if (!base::PathExists(file_path)) {
      if (!base::CreateDirectory(file_path))
        return NULL;
    }
    return new TestingProfile(file_path, NULL);
  }
};

// Create a greyscale image with certain size and grayscale value.
gfx::Image CreateGrayscaleImage(gfx::Size size, uint8_t greyscale_value) {
  SkBitmap result;
  result.allocN32Pixels(size.width(), size.height(), true);

  uint8_t* pixels_data = reinterpret_cast<uint8_t*>(result.getPixels());

  // Set greyscale value for all pixels.
  for (int y = 0; y < result.height(); ++y) {
    for (int x = 0; x < result.width(); ++x) {
      pixels_data[result.rowBytes() * y + x * result.bytesPerPixel()] =
          greyscale_value;
      pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 1] =
          greyscale_value;
      pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 2] =
          greyscale_value;
      pixels_data[result.rowBytes() * y + x * result.bytesPerPixel() + 3] =
          0xff;
    }
  }

  return gfx::Image::CreateFrom1xBitmap(result);
}

}  // namespace

class MockObserver : public DesktopMediaListObserver {
 public:
  MOCK_METHOD2(OnSourceAdded, void(DesktopMediaList* list, int index));
  MOCK_METHOD2(OnSourceRemoved, void(DesktopMediaList* list, int index));
  MOCK_METHOD3(OnSourceMoved,
               void(DesktopMediaList* list, int old_index, int new_index));
  MOCK_METHOD2(OnSourceNameChanged, void(DesktopMediaList* list, int index));
  MOCK_METHOD2(OnSourceThumbnailChanged,
               void(DesktopMediaList* list, int index));

  void VerifyAndClearExpectations() {
    testing::Mock::VerifyAndClearExpectations(this);
  }
};

ACTION_P2(CheckListSize, list, expected_list_size) {
  EXPECT_EQ(expected_list_size, list->GetSourceCount());
}

ACTION(QuitMessageLoop) {
  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE, base::RunLoop::QuitCurrentWhenIdleClosureDeprecated());
}

class TabDesktopMediaListTest : public testing::Test {
 protected:
  TabDesktopMediaListTest()
      : local_state_(TestingBrowserProcess::GetGlobal()) {}

  void AddWebcontents(int favicon_greyscale) {
    TabStripModel* tab_strip_model = browser_->tab_strip_model();
    ASSERT_TRUE(tab_strip_model);
    std::unique_ptr<WebContents> contents(
        content::WebContentsTester::CreateTestWebContents(
            profile_, content::SiteInstance::Create(profile_)));
    ASSERT_TRUE(contents);

    WebContentsTester::For(contents.get())
        ->SetLastActiveTime(base::TimeTicks::Now());

    // Get or create the transient NavigationEntry and add a title and a
    // favicon to it.
    content::NavigationEntry* entry =
        contents->GetController().GetTransientEntry();
    if (!entry) {
      std::unique_ptr<content::NavigationEntry> entry_new =
          content::NavigationController::CreateNavigationEntry(
              GURL("chrome://blank"), content::Referrer(),
              ui::PAGE_TRANSITION_LINK, false, std::string(), profile_,
              nullptr /* blob_url_loader_factory */);

      contents->GetController().SetTransientEntry(std::move(entry_new));
      entry = contents->GetController().GetTransientEntry();
    }

    contents->UpdateTitleForEntry(entry, base::ASCIIToUTF16("Test tab"));

    content::FaviconStatus favicon_info;
    favicon_info.image =
        CreateGrayscaleImage(gfx::Size(10, 10), favicon_greyscale);
    entry->GetFavicon() = favicon_info;

    manually_added_web_contents_.push_back(contents.get());
    tab_strip_model->AppendWebContents(std::move(contents), true);
  }

  void SetUp() override {
    manually_added_web_contents_.clear();
    rvh_test_enabler_.reset(new content::RenderViewHostTestEnabler());
    // Create a new temporary directory, and store the path.
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    TestingBrowserProcess::GetGlobal()->SetProfileManager(
        new UnittestProfileManager(temp_dir_.GetPath()));

#if defined(OS_CHROMEOS)
    base::CommandLine* cl = base::CommandLine::ForCurrentProcess();
    cl->AppendSwitch(switches::kTestType);
#endif

    // Create profile.
    ProfileManager* profile_manager = g_browser_process->profile_manager();
    ASSERT_TRUE(profile_manager);

    profile_ = profile_manager->GetLastUsedProfileAllowedByPolicy();
    ASSERT_TRUE(profile_);

    // Create browser.
    Browser::CreateParams profile_params(profile_, true);
    browser_ = CreateBrowserWithTestWindowForParams(&profile_params);
    ASSERT_TRUE(browser_);
    for (int i = 0; i < kDefaultSourceCount; i++) {
      AddWebcontents(i + 1);
    }
  }

  void TearDown() override {
    // TODO(erikchen): Tearing down the TabStripModel should just delete all its
    // owned WebContents. Then |manually_added_web_contents_| won't be
    // necessary. https://crbug.com/832879.
    TabStripModel* tab_strip_model = browser_->tab_strip_model();
    for (WebContents* contents : manually_added_web_contents_) {
      tab_strip_model->DetachWebContentsAt(
          tab_strip_model->GetIndexOfWebContents(contents));
    }
    manually_added_web_contents_.clear();

    browser_.reset();
    TestingBrowserProcess::GetGlobal()->SetProfileManager(NULL);
    base::RunLoop().RunUntilIdle();
    rvh_test_enabler_.reset();
  }

  void CreateDefaultList() {
    list_.reset(new TabDesktopMediaList());
    list_->SetThumbnailSize(gfx::Size(kThumbnailSize, kThumbnailSize));

    // Set update period to reduce the time it takes to run tests.
    // >0 to avoid unit test failure.
    list_->SetUpdatePeriod(base::TimeDelta::FromMilliseconds(1));
  }

  void InitializeAndVerify() {
    CreateDefaultList();

    // The tabs in media source list are sorted in decreasing time order. The
    // latest one is listed first. However, tabs are added to TabStripModel in
    // increasing time order, the oldest one is added first.
    {
      testing::InSequence dummy;

      for (int i = 0; i < kDefaultSourceCount; i++) {
        EXPECT_CALL(observer_, OnSourceAdded(list_.get(), i))
            .WillOnce(CheckListSize(list_.get(), i + 1));
      }

      for (int i = 0; i < kDefaultSourceCount - 1; i++) {
        EXPECT_CALL(observer_, OnSourceThumbnailChanged(
                                   list_.get(), kDefaultSourceCount - 1 - i));
      }
      EXPECT_CALL(observer_, OnSourceThumbnailChanged(list_.get(), 0))
          .WillOnce(QuitMessageLoop());
    }

    list_->StartUpdating(&observer_);
    base::RunLoop().Run();

    for (int i = 0; i < kDefaultSourceCount; ++i) {
      EXPECT_EQ(list_->GetSource(i).id.type,
                content::DesktopMediaID::TYPE_WEB_CONTENTS);
    }

    observer_.VerifyAndClearExpectations();
  }

  // The path to temporary directory used to contain the test operations.
  base::ScopedTempDir temp_dir_;
  ScopedTestingLocalState local_state_;

  std::unique_ptr<content::RenderViewHostTestEnabler> rvh_test_enabler_;
  Profile* profile_;
  std::unique_ptr<Browser> browser_;

  // Must be listed before |list_|, so it's destroyed last.
  MockObserver observer_;
  std::unique_ptr<TabDesktopMediaList> list_;
  std::vector<WebContents*> manually_added_web_contents_;

  content::TestBrowserThreadBundle thread_bundle_;

#if defined(OS_CHROMEOS)
  chromeos::ScopedCrosSettingsTestHelper cros_settings_test_helper_;
  chromeos::ScopedTestUserManager test_user_manager_;
#endif

  DISALLOW_COPY_AND_ASSIGN(TabDesktopMediaListTest);
};

TEST_F(TabDesktopMediaListTest, AddTab) {
  InitializeAndVerify();

  AddWebcontents(10);

  EXPECT_CALL(observer_, OnSourceAdded(list_.get(), 0))
      .WillOnce(CheckListSize(list_.get(), kDefaultSourceCount + 1));
  EXPECT_CALL(observer_, OnSourceThumbnailChanged(list_.get(), 0))
      .WillOnce(QuitMessageLoop());

  base::RunLoop().Run();

  list_.reset();
}

TEST_F(TabDesktopMediaListTest, RemoveTab) {
  InitializeAndVerify();

  TabStripModel* tab_strip_model = browser_->tab_strip_model();
  ASSERT_TRUE(tab_strip_model);
  std::unique_ptr<WebContents> released_web_contents =
      tab_strip_model->DetachWebContentsAt(kDefaultSourceCount - 1);
  for (auto it = manually_added_web_contents_.begin();
       it != manually_added_web_contents_.end(); ++it) {
    if (*it == released_web_contents.get()) {
      manually_added_web_contents_.erase(it);
      break;
    }
  }

  EXPECT_CALL(observer_, OnSourceRemoved(list_.get(), 0))
      .WillOnce(
          testing::DoAll(CheckListSize(list_.get(), kDefaultSourceCount - 1),
                         QuitMessageLoop()));

  base::RunLoop().Run();

  list_.reset();
}

TEST_F(TabDesktopMediaListTest, MoveTab) {
  InitializeAndVerify();

  // Swap the two media sources by swap their time stamps.
  TabStripModel* tab_strip_model = browser_->tab_strip_model();
  ASSERT_TRUE(tab_strip_model);

  WebContents* contents0 = tab_strip_model->GetWebContentsAt(0);
  ASSERT_TRUE(contents0);
  base::TimeTicks t0 = contents0->GetLastActiveTime();
  WebContents* contents1 = tab_strip_model->GetWebContentsAt(1);
  ASSERT_TRUE(contents1);
  base::TimeTicks t1 = contents1->GetLastActiveTime();

  WebContentsTester::For(contents0)->SetLastActiveTime(t1);
  WebContentsTester::For(contents1)->SetLastActiveTime(t0);

  EXPECT_CALL(observer_, OnSourceMoved(list_.get(), 1, 0))
      .WillOnce(testing::DoAll(CheckListSize(list_.get(), kDefaultSourceCount),
                               QuitMessageLoop()));

  base::RunLoop().Run();

  list_.reset();
}

TEST_F(TabDesktopMediaListTest, UpdateTitle) {
  InitializeAndVerify();

  // Change tab's title.
  TabStripModel* tab_strip_model = browser_->tab_strip_model();
  ASSERT_TRUE(tab_strip_model);
  WebContents* contents =
      tab_strip_model->GetWebContentsAt(kDefaultSourceCount - 1);
  ASSERT_TRUE(contents);
  content::NavigationController& controller = contents->GetController();
  contents->UpdateTitleForEntry(controller.GetTransientEntry(),
                                base::ASCIIToUTF16("New test tab"));

  EXPECT_CALL(observer_, OnSourceNameChanged(list_.get(), 0))
      .WillOnce(QuitMessageLoop());

  base::RunLoop().Run();

  EXPECT_EQ(list_->GetSource(0).name, base::UTF8ToUTF16("New test tab"));

  list_.reset();
}

TEST_F(TabDesktopMediaListTest, UpdateThumbnail) {
  InitializeAndVerify();

  // Change tab's favicon.
  TabStripModel* tab_strip_model = browser_->tab_strip_model();
  ASSERT_TRUE(tab_strip_model);
  WebContents* contents =
      tab_strip_model->GetWebContentsAt(kDefaultSourceCount - 1);
  ASSERT_TRUE(contents);

  content::FaviconStatus favicon_info;
  favicon_info.image = CreateGrayscaleImage(gfx::Size(10, 10), 100);
  contents->GetController().GetTransientEntry()->GetFavicon() = favicon_info;

  EXPECT_CALL(observer_, OnSourceThumbnailChanged(list_.get(), 0))
      .WillOnce(QuitMessageLoop());

  base::RunLoop().Run();

  list_.reset();
}
