// 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/profiles/profile_destroyer.h"

#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_instance.h"

class TestingOffTheRecordDestructionProfile : public TestingProfile {
 public:
  TestingOffTheRecordDestructionProfile()
      : TestingProfile(base::FilePath(),
                       NULL,
                       scoped_refptr<ExtensionSpecialStoragePolicy>()
                       scoped_ptr<PrefServiceSyncable>(),
                       true,
                       TestingFactories()),
        destroyed_otr_profile_(false) {
    set_incognito(true);
  }
  virtual void DestroyOffTheRecordProfile() OVERRIDE {
    destroyed_otr_profile_ = true;
  }
  bool destroyed_otr_profile_;

  DISALLOW_COPY_AND_ASSIGN(TestingOffTheRecordDestructionProfile);
};

class TestingOriginalDestructionProfile : public TestingProfile {
 public:
  TestingOriginalDestructionProfile() : destroyed_otr_profile_(false) {
    DCHECK_EQ(kNull, living_instance_);
    living_instance_ = this;
  }
  virtual ~TestingOriginalDestructionProfile() {
    DCHECK_EQ(this, living_instance_);
    living_instance_ = NULL;
  }
  virtual void DestroyOffTheRecordProfile() OVERRIDE {
    SetOffTheRecordProfile(NULL);
    destroyed_otr_profile_ = true;
  }
  bool destroyed_otr_profile_;
  static TestingOriginalDestructionProfile* living_instance_;

  // This is to avoid type casting in DCHECK_EQ & EXPECT_NE.
  static const TestingOriginalDestructionProfile* kNull;

  DISALLOW_COPY_AND_ASSIGN(TestingOriginalDestructionProfile);
};
const TestingOriginalDestructionProfile*
    TestingOriginalDestructionProfile::kNull = NULL;

TestingOriginalDestructionProfile*
    TestingOriginalDestructionProfile::living_instance_ = NULL;

class ProfileDestroyerTest : public BrowserWithTestWindowTest {
 public:
  ProfileDestroyerTest() : off_the_record_profile_(NULL) {}

 protected:
  virtual TestingProfile* CreateProfile() OVERRIDE {
    if (off_the_record_profile_ == NULL)
      off_the_record_profile_ = new TestingOffTheRecordDestructionProfile();
    return off_the_record_profile_;
  }
  TestingOffTheRecordDestructionProfile* off_the_record_profile_;

  DISALLOW_COPY_AND_ASSIGN(ProfileDestroyerTest);
};

TEST_F(ProfileDestroyerTest, DelayProfileDestruction) {
  scoped_refptr<content::SiteInstance> instance1(
      content::SiteInstance::Create(off_the_record_profile_));
  scoped_ptr<content::RenderProcessHost> render_process_host1;
  render_process_host1.reset(instance1->GetProcess());
  ASSERT_TRUE(render_process_host1.get() != NULL);

  scoped_refptr<content::SiteInstance> instance2(
      content::SiteInstance::Create(off_the_record_profile_));
  scoped_ptr<content::RenderProcessHost> render_process_host2;
  render_process_host2.reset(instance2->GetProcess());
  ASSERT_TRUE(render_process_host2.get() != NULL);

  // destroying the browser should not destroy the off the record profile...
  set_browser(NULL);
  EXPECT_FALSE(off_the_record_profile_->destroyed_otr_profile_);

  // until we destroy the render process host holding on to it...
  render_process_host1.release()->Cleanup();

  // And asynchronicity kicked in properly.
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_FALSE(off_the_record_profile_->destroyed_otr_profile_);

  // I meant, ALL the render process hosts... :-)
  render_process_host2.release()->Cleanup();
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_TRUE(off_the_record_profile_->destroyed_otr_profile_);
}

TEST_F(ProfileDestroyerTest, DelayOriginalProfileDestruction) {
  TestingOriginalDestructionProfile* original_profile =
      new TestingOriginalDestructionProfile;

  TestingOffTheRecordDestructionProfile* off_the_record_profile =
      new TestingOffTheRecordDestructionProfile;

  original_profile->SetOffTheRecordProfile(off_the_record_profile);

  scoped_refptr<content::SiteInstance> instance1(
      content::SiteInstance::Create(off_the_record_profile));
  scoped_ptr<content::RenderProcessHost> render_process_host1;
  render_process_host1.reset(instance1->GetProcess());
  ASSERT_TRUE(render_process_host1.get() != NULL);

  // Trying to destroy the original profile should be delayed until associated
  // off the record profile is released by all render process hosts.
  ProfileDestroyer::DestroyProfileWhenAppropriate(original_profile);
  EXPECT_NE(TestingOriginalDestructionProfile::kNull,
            TestingOriginalDestructionProfile::living_instance_);
  EXPECT_FALSE(original_profile->destroyed_otr_profile_);

  render_process_host1.release()->Cleanup();
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(NULL, TestingOriginalDestructionProfile::living_instance_);

  // And the same protection should apply to the main profile.
  TestingOriginalDestructionProfile* main_profile =
      new TestingOriginalDestructionProfile;
  scoped_refptr<content::SiteInstance> instance2(
      content::SiteInstance::Create(main_profile));
  scoped_ptr<content::RenderProcessHost> render_process_host2;
  render_process_host2.reset(instance2->GetProcess());
  ASSERT_TRUE(render_process_host2.get() != NULL);

  ProfileDestroyer::DestroyProfileWhenAppropriate(main_profile);
  EXPECT_EQ(main_profile, TestingOriginalDestructionProfile::living_instance_);
  render_process_host2.release()->Cleanup();
  base::MessageLoop::current()->RunUntilIdle();
  EXPECT_EQ(NULL, TestingOriginalDestructionProfile::living_instance_);
}
