// 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 <algorithm>

#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/path_service.h"
#include "extensions/common/constants.h"
#include "extensions/common/extension_paths.h"
#include "extensions/common/extension_resource.h"
#include "extensions/common/id_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "ui/base/l10n/l10n_util.h"

namespace extensions {

TEST(ExtensionResourceTest, CreateEmptyResource) {
  ExtensionResource resource;

  EXPECT_TRUE(resource.extension_root().empty());
  EXPECT_TRUE(resource.relative_path().empty());
  EXPECT_TRUE(resource.GetFilePath().empty());
}

const base::FilePath::StringType ToLower(
    const base::FilePath::StringType& in_str) {
  base::FilePath::StringType str(in_str);
  std::transform(str.begin(), str.end(), str.begin(), tolower);
  return str;
}

TEST(ExtensionResourceTest, CreateWithMissingResourceOnDisk) {
  base::FilePath root_path;
  ASSERT_TRUE(PathService::Get(DIR_TEST_DATA, &root_path));
  base::FilePath relative_path;
  relative_path = relative_path.AppendASCII("cira.js");
  std::string extension_id = id_util::GenerateId("test");
  ExtensionResource resource(extension_id, root_path, relative_path);

  // The path doesn't exist on disk, we will be returned an empty path.
  EXPECT_EQ(root_path.value(), resource.extension_root().value());
  EXPECT_EQ(relative_path.value(), resource.relative_path().value());
  EXPECT_TRUE(resource.GetFilePath().empty());
}

TEST(ExtensionResourceTest, ResourcesOutsideOfPath) {
  base::ScopedTempDir temp;
  ASSERT_TRUE(temp.CreateUniqueTempDir());

  base::FilePath inner_dir = temp.path().AppendASCII("directory");
  ASSERT_TRUE(base::CreateDirectory(inner_dir));
  base::FilePath sub_dir = inner_dir.AppendASCII("subdir");
  ASSERT_TRUE(base::CreateDirectory(sub_dir));
  base::FilePath inner_file = inner_dir.AppendASCII("inner");
  base::FilePath outer_file = temp.path().AppendASCII("outer");
  ASSERT_TRUE(file_util::WriteFile(outer_file, "X", 1));
  ASSERT_TRUE(file_util::WriteFile(inner_file, "X", 1));
  std::string extension_id = id_util::GenerateId("test");

#if defined(OS_POSIX)
  base::FilePath symlink_file = inner_dir.AppendASCII("symlink");
  base::CreateSymbolicLink(
      base::FilePath().AppendASCII("..").AppendASCII("outer"),
      symlink_file);
#endif

  // A non-packing extension should be able to access the file within the
  // directory.
  ExtensionResource r1(extension_id, inner_dir,
                       base::FilePath().AppendASCII("inner"));
  EXPECT_FALSE(r1.GetFilePath().empty());

  // ... but not a relative path that walks out of |inner_dir|.
  ExtensionResource r2(extension_id, inner_dir,
                       base::FilePath().AppendASCII("..").AppendASCII("outer"));
  EXPECT_TRUE(r2.GetFilePath().empty());

  // A packing extension should also be able to access the file within the
  // directory.
  ExtensionResource r3(extension_id, inner_dir,
                       base::FilePath().AppendASCII("inner"));
  r3.set_follow_symlinks_anywhere();
  EXPECT_FALSE(r3.GetFilePath().empty());

  // ... but, again, not a relative path that walks out of |inner_dir|.
  ExtensionResource r4(extension_id, inner_dir,
                       base::FilePath().AppendASCII("..").AppendASCII("outer"));
  r4.set_follow_symlinks_anywhere();
  EXPECT_TRUE(r4.GetFilePath().empty());

  // ... and not even when clever current-directory syntax is present. Note
  // that the path for this test case can't start with the current directory
  // component due to quirks in FilePath::Append(), and the path must exist.
  ExtensionResource r4a(
      extension_id, inner_dir,
      base::FilePath().AppendASCII("subdir").AppendASCII(".").AppendASCII("..").
      AppendASCII("..").AppendASCII("outer"));
  r4a.set_follow_symlinks_anywhere();
  EXPECT_TRUE(r4a.GetFilePath().empty());

#if defined(OS_POSIX)
  // The non-packing extension should also not be able to access a resource that
  // symlinks out of the directory.
  ExtensionResource r5(extension_id, inner_dir,
                       base::FilePath().AppendASCII("symlink"));
  EXPECT_TRUE(r5.GetFilePath().empty());

  // ... but a packing extension can.
  ExtensionResource r6(extension_id, inner_dir,
                       base::FilePath().AppendASCII("symlink"));
  r6.set_follow_symlinks_anywhere();
  EXPECT_FALSE(r6.GetFilePath().empty());
#endif
}

TEST(ExtensionResourceTest, CreateWithAllResourcesOnDisk) {
  base::ScopedTempDir temp;
  ASSERT_TRUE(temp.CreateUniqueTempDir());

  // Create resource in the extension root.
  const char* filename = "res.ico";
  base::FilePath root_resource = temp.path().AppendASCII(filename);
  std::string data = "some foo";
  ASSERT_TRUE(file_util::WriteFile(root_resource, data.c_str(), data.length()));

  // Create l10n resources (for current locale and its parents).
  base::FilePath l10n_path =
      temp.path().Append(kLocaleFolder);
  ASSERT_TRUE(base::CreateDirectory(l10n_path));

  std::vector<std::string> locales;
  l10n_util::GetParentLocales(l10n_util::GetApplicationLocale(std::string()),
                              &locales);
  ASSERT_FALSE(locales.empty());
  for (size_t i = 0; i < locales.size(); i++) {
    base::FilePath make_path;
    make_path = l10n_path.AppendASCII(locales[i]);
    ASSERT_TRUE(base::CreateDirectory(make_path));
    ASSERT_TRUE(file_util::WriteFile(make_path.AppendASCII(filename),
        data.c_str(), data.length()));
  }

  base::FilePath path;
  std::string extension_id = id_util::GenerateId("test");
  ExtensionResource resource(extension_id, temp.path(),
                             base::FilePath().AppendASCII(filename));
  base::FilePath resolved_path = resource.GetFilePath();

  base::FilePath expected_path;
  // Expect default path only, since fallback logic is disabled.
  // See http://crbug.com/27359.
  expected_path = base::MakeAbsoluteFilePath(root_resource);
  ASSERT_FALSE(expected_path.empty());

  EXPECT_EQ(ToLower(expected_path.value()), ToLower(resolved_path.value()));
  EXPECT_EQ(ToLower(temp.path().value()),
            ToLower(resource.extension_root().value()));
  EXPECT_EQ(ToLower(base::FilePath().AppendASCII(filename).value()),
            ToLower(resource.relative_path().value()));
}

}  // namespace extensions
