// Copyright 2013 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/extensions/external_provider_impl.h"

#include "base/command_line.h"
#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/prefs/testing_pref_service.h"
#include "base/strings/stringprintf.h"
#include "base/test/scoped_path_override.h"
#include "chrome/browser/chrome_notification_types.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/browser/extensions/extension_service_test_base.h"
#include "chrome/browser/extensions/updater/extension_cache_fake.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/extensions/extension_constants.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "content/public/browser/notification_service.h"
#include "content/public/test/test_utils.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "testing/gmock/include/gmock/gmock.h"

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/customization_document.h"
#include "chrome/browser/chromeos/login/users/fake_user_manager.h"
#include "chromeos/system/mock_statistics_provider.h"
#include "chromeos/system/statistics_provider.h"
#endif

using ::testing::_;
using ::testing::NotNull;
using ::testing::Return;

namespace extensions {

namespace {

using namespace net::test_server;

const char kManifestPath[] = "/update_manifest";
const char kAppPath[] = "/app.crx";

class ExternalProviderImplTest : public ExtensionServiceTestBase {
 public:
  ExternalProviderImplTest() {}
  virtual ~ExternalProviderImplTest() {}

  void InitServiceWithExternalProviders() {
#if defined(OS_CHROMEOS)
    chromeos::ScopedUserManagerEnabler scoped_user_manager(
        new chromeos::FakeUserManager);
#endif
    InitializeExtensionServiceWithUpdater();

    ProviderCollection providers;
    extensions::ExternalProviderImpl::CreateExternalProviders(
        service_, profile_.get(), &providers);

    for (ProviderCollection::iterator i = providers.begin();
         i != providers.end();
         ++i) {
      service_->AddProviderForTesting(i->release());
    }
  }

  // ExtensionServiceTestBase overrides:
  virtual void SetUp() OVERRIDE {
    ExtensionServiceTestBase::SetUp();
    test_server_.reset(new EmbeddedTestServer());

#if defined(OS_CHROMEOS)
    TestingBrowserProcess::GetGlobal()->SetLocalState(&local_state_);
    chromeos::ServicesCustomizationDocument::RegisterPrefs(
        local_state_.registry());
#endif

    ASSERT_TRUE(test_server_->InitializeAndWaitUntilReady());
    test_server_->RegisterRequestHandler(
        base::Bind(&ExternalProviderImplTest::HandleRequest,
                   base::Unretained(this)));

    test_extension_cache_.reset(new ExtensionCacheFake());

    CommandLine* cmdline = CommandLine::ForCurrentProcess();
    cmdline->AppendSwitchASCII(switches::kAppsGalleryUpdateURL,
                               test_server_->GetURL(kManifestPath).spec());
#if defined(OS_CHROMEOS)
    chromeos::system::StatisticsProvider::SetTestProvider(
        &mock_statistics_provider_);
    EXPECT_CALL(mock_statistics_provider_, GetMachineStatistic(_, NotNull()))
        .WillRepeatedly(Return(false));
#endif
  }

  virtual void TearDown() OVERRIDE {
#if defined(OS_CHROMEOS)
    chromeos::system::StatisticsProvider::SetTestProvider(NULL);
    TestingBrowserProcess::GetGlobal()->SetLocalState(NULL);
#endif
  }

 private:
  scoped_ptr<HttpResponse> HandleRequest(const HttpRequest& request) {
    GURL url = test_server_->GetURL(request.relative_url);
    if (url.path() == kManifestPath) {
      scoped_ptr<BasicHttpResponse> response(new BasicHttpResponse);
      response->set_code(net::HTTP_OK);
      response->set_content(base::StringPrintf(
          "<?xml version='1.0' encoding='UTF-8'?>\n"
          "<gupdate xmlns='http://www.google.com/update2/response' "
              "protocol='2.0'>\n"
          "  <app appid='%s'>\n"
          "    <updatecheck codebase='%s' version='1.0' />\n"
          "  </app>\n"
          "</gupdate>",
          extension_misc::kInAppPaymentsSupportAppId,
          test_server_->GetURL(kAppPath).spec().c_str()));
      response->set_content_type("text/xml");
      return response.PassAs<HttpResponse>();
    }
    if (url.path() == kAppPath) {
      base::FilePath test_data_dir;
      PathService::Get(chrome::DIR_TEST_DATA, &test_data_dir);
      std::string contents;
      base::ReadFileToString(
          test_data_dir.AppendASCII("extensions/dummyiap.crx"),
          &contents);
      scoped_ptr<BasicHttpResponse> response(new BasicHttpResponse);
      response->set_code(net::HTTP_OK);
      response->set_content(contents);
      return response.PassAs<HttpResponse>();
    }

    return scoped_ptr<HttpResponse>();
  }

  scoped_ptr<EmbeddedTestServer> test_server_;
  scoped_ptr<ExtensionCacheFake> test_extension_cache_;
#if defined(OS_CHROMEOS)
  chromeos::system::MockStatisticsProvider mock_statistics_provider_;
  TestingPrefServiceSimple local_state_;
#endif

  DISALLOW_COPY_AND_ASSIGN(ExternalProviderImplTest);
};

}  // namespace

// flaky, disabling on branch only
TEST_F(ExternalProviderImplTest, DISABLED_InAppPayments) {
  InitServiceWithExternalProviders();

  scoped_refptr<content::MessageLoopRunner> runner =
      new content::MessageLoopRunner;
  service_->set_external_updates_finished_callback_for_test(
      runner->QuitClosure());

  service_->CheckForExternalUpdates();
  runner->Run();

  EXPECT_TRUE(service_->GetInstalledExtension(
      extension_misc::kInAppPaymentsSupportAppId));
  EXPECT_TRUE(service_->IsExtensionEnabled(
      extension_misc::kInAppPaymentsSupportAppId));
}

}  // namespace extensions
