// 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 "extensions/common/extension_resource.h"

#include <stddef.h>

#include "base/files/file_util.h"
#include "base/logging.h"
#include "base/threading/thread_restrictions.h"

namespace extensions {

ExtensionResource::ExtensionResource() : follow_symlinks_anywhere_(false) {
}

ExtensionResource::ExtensionResource(const std::string& extension_id,
                                     const base::FilePath& extension_root,
                                     const base::FilePath& relative_path)
    : extension_id_(extension_id),
      extension_root_(extension_root),
      relative_path_(relative_path),
      follow_symlinks_anywhere_(false) {
}

ExtensionResource::ExtensionResource(const ExtensionResource& other) = default;

ExtensionResource::~ExtensionResource() {}

void ExtensionResource::set_follow_symlinks_anywhere() {
  follow_symlinks_anywhere_ = true;
}

const base::FilePath& ExtensionResource::GetFilePath() const {
  if (extension_root_.empty() || relative_path_.empty()) {
    DCHECK(full_resource_path_.empty());
    return full_resource_path_;
  }

  // We've already checked, just return last value.
  if (!full_resource_path_.empty())
    return full_resource_path_;

  full_resource_path_ = GetFilePath(
      extension_root_, relative_path_,
      follow_symlinks_anywhere_ ?
          FOLLOW_SYMLINKS_ANYWHERE : SYMLINKS_MUST_RESOLVE_WITHIN_ROOT);
  return full_resource_path_;
}

// static
base::FilePath ExtensionResource::GetFilePath(
    const base::FilePath& extension_root,
    const base::FilePath& relative_path,
    SymlinkPolicy symlink_policy) {
  // We need to resolve the parent references in the extension_root
  // path on its own because IsParent doesn't like parent references.
  base::FilePath clean_extension_root(
      base::MakeAbsoluteFilePath(extension_root));
  if (clean_extension_root.empty())
    return base::FilePath();

  base::FilePath full_path = clean_extension_root.Append(relative_path);

  // If we are allowing the file to be a symlink outside of the root, then the
  // path before resolving the symlink must still be within it.
  if (symlink_policy == FOLLOW_SYMLINKS_ANYWHERE) {
    std::vector<base::FilePath::StringType> components;
    relative_path.GetComponents(&components);
    int depth = 0;

    for (std::vector<base::FilePath::StringType>::const_iterator
         i = components.begin(); i != components.end(); i++) {
      if (*i == base::FilePath::kParentDirectory) {
        depth--;
      } else if (*i != base::FilePath::kCurrentDirectory) {
        depth++;
      }
      if (depth < 0) {
        return base::FilePath();
      }
    }
  }

  // We must resolve the absolute path of the combined path when
  // the relative path contains references to a parent folder (i.e., '..').
  // We also check if the path exists because the posix version of
  // MakeAbsoluteFilePath will fail if the path doesn't exist, and we want the
  // same behavior on Windows... So until the posix and Windows version of
  // MakeAbsoluteFilePath are unified, we need an extra call to PathExists,
  // unfortunately.
  // TODO(mad): Fix this once MakeAbsoluteFilePath is unified.
  full_path = base::MakeAbsoluteFilePath(full_path);
  if (base::PathExists(full_path) &&
      (symlink_policy == FOLLOW_SYMLINKS_ANYWHERE ||
       clean_extension_root.IsParent(full_path))) {
    return full_path;
  }

  return base::FilePath();
}

// Unit-testing helpers.
base::FilePath::StringType ExtensionResource::NormalizeSeperators(
    const base::FilePath::StringType& path) const {
#if defined(FILE_PATH_USES_WIN_SEPARATORS)
  base::FilePath::StringType win_path = path;
  for (size_t i = 0; i < win_path.length(); i++) {
    if (base::FilePath::IsSeparator(win_path[i]))
      win_path[i] = base::FilePath::kSeparators[0];
  }
  return win_path;
#else
  return path;
#endif  // FILE_PATH_USES_WIN_SEPARATORS
}

bool ExtensionResource::ComparePathWithDefault(
    const base::FilePath& path) const {
  // Make sure we have a cached value to test against...
  if (full_resource_path_.empty())
    GetFilePath();
  if (NormalizeSeperators(path.value()) ==
    NormalizeSeperators(full_resource_path_.value())) {
    return true;
  } else {
    return false;
  }
}

}  // namespace extensions
