// 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 <string>
#include <vector>

#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_ptr.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/convert_user_script.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/extensions/manifest_handlers/content_scripts_handler.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace extensions {

namespace {

static void AddPattern(URLPatternSet* extent, const std::string& pattern) {
  int schemes = URLPattern::SCHEME_ALL;
  extent->AddPattern(URLPattern(schemes, pattern));
}

}

class ExtensionFromUserScript : public testing::Test {
};

TEST_F(ExtensionFromUserScript, Basic) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_basic.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("My user script", extension->name());
  EXPECT_EQ("2.2.2", extension->VersionString());
  EXPECT_EQ("Does totally awesome stuff.", extension->description());
  EXPECT_EQ("IhCFCg9PMQTAcJdc9ytUP99WME+4yh6aMnM1uupkovo=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  EXPECT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
  ASSERT_EQ(2u, script.globs().size());
  EXPECT_EQ("http://www.google.com/*", script.globs().at(0));
  EXPECT_EQ("http://www.yahoo.com/*", script.globs().at(1));
  ASSERT_EQ(1u, script.exclude_globs().size());
  EXPECT_EQ("*foo*", script.exclude_globs().at(0));
  ASSERT_EQ(1u, script.url_patterns().patterns().size());
  EXPECT_EQ("http://www.google.com/*",
            script.url_patterns().begin()->GetAsString());
  ASSERT_EQ(1u, script.exclude_url_patterns().patterns().size());
  EXPECT_EQ("http://www.google.com/foo*",
            script.exclude_url_patterns().begin()->GetAsString());
  EXPECT_TRUE(script.emulate_greasemonkey());

  // Make sure the files actually exist on disk.
  EXPECT_TRUE(base::PathExists(
      extension->path().Append(script.js_scripts()[0].relative_path())));
  EXPECT_TRUE(base::PathExists(
      extension->path().Append(kManifestFilename)));
}

TEST_F(ExtensionFromUserScript, NoMetadata) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_no_metadata.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo/bar.user.js?monkey"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("bar.user.js", extension->name());
  EXPECT_EQ("1.0", extension->VersionString());
  EXPECT_EQ("", extension->description());
  EXPECT_EQ("k1WxKx54hX6tfl5gQaXD/m4d9QUMwRdXWM4RW+QkWcY=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  ASSERT_EQ(1u, script.globs().size());
  EXPECT_EQ("*", script.globs()[0]);
  EXPECT_EQ(0u, script.exclude_globs().size());
  EXPECT_TRUE(script.emulate_greasemonkey());

  URLPatternSet expected;
  AddPattern(&expected, "http://*/*");
  AddPattern(&expected, "https://*/*");
  EXPECT_EQ(expected, script.url_patterns());

  // Make sure the files actually exist on disk.
  EXPECT_TRUE(base::PathExists(
      extension->path().Append(script.js_scripts()[0].relative_path())));
  EXPECT_TRUE(base::PathExists(
      extension->path().Append(kManifestFilename)));
}

TEST_F(ExtensionFromUserScript, NotUTF8) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_not_utf8.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo/bar.user.js?monkey"),
      extensions_dir.path(), &error));

  ASSERT_FALSE(extension.get());
  EXPECT_EQ(base::ASCIIToUTF16("User script must be UTF8 encoded."), error);
}

TEST_F(ExtensionFromUserScript, RunAtDocumentStart) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_run_at_start.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("Document Start Test", extension->name());
  EXPECT_EQ("This script tests document-start", extension->description());
  EXPECT_EQ("RjmyI7+Gp/YHcW1qnu4xDxkJcL4cV4kTzdCA4BajCbk=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  // Validate run location.
  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  EXPECT_EQ(UserScript::DOCUMENT_START, script.run_location());
}

TEST_F(ExtensionFromUserScript, RunAtDocumentEnd) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_run_at_end.user.js");

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("Document End Test", extension->name());
  EXPECT_EQ("This script tests document-end", extension->description());
  EXPECT_EQ("cpr5i8Mi24FzECV8UJe6tanwlU8SWesZosJ915YISvQ=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  // Validate run location.
  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  EXPECT_EQ(UserScript::DOCUMENT_END, script.run_location());
}

TEST_F(ExtensionFromUserScript, RunAtDocumentIdle) {
  base::ScopedTempDir extensions_dir;
  ASSERT_TRUE(extensions_dir.CreateUniqueTempDir());

  base::FilePath test_file;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &test_file));
  test_file = test_file.AppendASCII("extensions")
                       .AppendASCII("user_script_run_at_idle.user.js");
  ASSERT_TRUE(base::PathExists(test_file)) << test_file.value();

  base::string16 error;
  scoped_refptr<Extension> extension(ConvertUserScriptToExtension(
      test_file, GURL("http://www.google.com/foo"),
      extensions_dir.path(), &error));

  ASSERT_TRUE(extension.get());
  EXPECT_EQ(base::string16(), error);

  // Use a temp dir so that the extensions dir will clean itself up.
  base::ScopedTempDir ext_dir;
  EXPECT_TRUE(ext_dir.Set(extension->path()));

  // Validate generated extension metadata.
  EXPECT_EQ("Document Idle Test", extension->name());
  EXPECT_EQ("This script tests document-idle", extension->description());
  EXPECT_EQ("kHnHKec3O/RKKo5/Iu1hKqe4wQERthL0639isNtsfiY=",
            extension->public_key());
  EXPECT_EQ(Manifest::TYPE_USER_SCRIPT, extension->GetType());

  // Validate run location.
  ASSERT_EQ(1u, ContentScriptsInfo::GetContentScripts(extension.get()).size());
  const UserScript& script =
      ContentScriptsInfo::GetContentScripts(extension.get())[0];
  EXPECT_EQ(UserScript::DOCUMENT_IDLE, script.run_location());
}

}  // namespace extensions
