// Copyright (c) 2006-2008 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 "base/path_service.h"

#ifdef OS_WIN
#include <windows.h>
#include <shellapi.h>
#include <shlobj.h>
#endif

#include "base/file_path.h"
#include "base/file_util.h"
#include "base/hash_tables.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/synchronization/lock.h"

namespace base {
  bool PathProvider(int key, FilePath* result);
#if defined(OS_WIN)
  bool PathProviderWin(int key, FilePath* result);
#elif defined(OS_MACOSX)
  bool PathProviderMac(int key, FilePath* result);
#elif defined(OS_POSIX)
  bool PathProviderPosix(int key, FilePath* result);
#endif
}

namespace {

typedef base::hash_map<int, FilePath> PathMap;

// We keep a linked list of providers.  In a debug build we ensure that no two
// providers claim overlapping keys.
struct Provider {
  PathService::ProviderFunc func;
  struct Provider* next;
#ifndef NDEBUG
  int key_start;
  int key_end;
#endif
  bool is_static;
};

static Provider base_provider = {
  base::PathProvider,
  NULL,
#ifndef NDEBUG
  base::PATH_START,
  base::PATH_END,
#endif
  true
};

#if defined(OS_WIN)
static Provider base_provider_win = {
  base::PathProviderWin,
  &base_provider,
#ifndef NDEBUG
  base::PATH_WIN_START,
  base::PATH_WIN_END,
#endif
  true
};
#endif

#if defined(OS_MACOSX)
static Provider base_provider_mac = {
  base::PathProviderMac,
  &base_provider,
#ifndef NDEBUG
  base::PATH_MAC_START,
  base::PATH_MAC_END,
#endif
  true
};
#endif

#if defined(OS_POSIX) && !defined(OS_MACOSX)
static Provider base_provider_posix = {
  base::PathProviderPosix,
  &base_provider,
#ifndef NDEBUG
  0,
  0,
#endif
  true
};
#endif


struct PathData {
  base::Lock lock;
  PathMap cache;        // Cache mappings from path key to path value.
  PathMap overrides;    // Track path overrides.
  Provider* providers;  // Linked list of path service providers.

  PathData() {
#if defined(OS_WIN)
    providers = &base_provider_win;
#elif defined(OS_MACOSX)
    providers = &base_provider_mac;
#elif defined(OS_POSIX)
    providers = &base_provider_posix;
#endif
  }

  ~PathData() {
    Provider* p = providers;
    while (p) {
      Provider* next = p->next;
      if (!p->is_static)
        delete p;
      p = next;
    }
  }
};

static base::LazyInstance<PathData> g_path_data(base::LINKER_INITIALIZED);

static PathData* GetPathData() {
  return g_path_data.Pointer();
}

}  // namespace


// static
bool PathService::GetFromCache(int key, FilePath* result) {
  PathData* path_data = GetPathData();
  base::AutoLock scoped_lock(path_data->lock);

  // check for a cached version
  PathMap::const_iterator it = path_data->cache.find(key);
  if (it != path_data->cache.end()) {
    *result = it->second;
    return true;
  }
  return false;
}

// static
bool PathService::GetFromOverrides(int key, FilePath* result) {
  PathData* path_data = GetPathData();
  base::AutoLock scoped_lock(path_data->lock);

  // check for an overriden version.
  PathMap::const_iterator it = path_data->overrides.find(key);
  if (it != path_data->overrides.end()) {
    *result = it->second;
    return true;
  }
  return false;
}

// static
void PathService::AddToCache(int key, const FilePath& path) {
  PathData* path_data = GetPathData();
  base::AutoLock scoped_lock(path_data->lock);
  // Save the computed path in our cache.
  path_data->cache[key] = path;
}

// TODO(brettw): this function does not handle long paths (filename > MAX_PATH)
// characters). This isn't supported very well by Windows right now, so it is
// moot, but we should keep this in mind for the future.
// static
bool PathService::Get(int key, FilePath* result) {
  PathData* path_data = GetPathData();
  DCHECK(path_data);
  DCHECK(result);
  DCHECK(key >= base::DIR_CURRENT);

  // special case the current directory because it can never be cached
  if (key == base::DIR_CURRENT)
    return file_util::GetCurrentDirectory(result);

  if (GetFromCache(key, result))
    return true;

  if (GetFromOverrides(key, result))
    return true;

  FilePath path;

  // search providers for the requested path
  // NOTE: it should be safe to iterate here without the lock
  // since RegisterProvider always prepends.
  Provider* provider = path_data->providers;
  while (provider) {
    if (provider->func(key, &path))
      break;
    DCHECK(path.empty()) << "provider should not have modified path";
    provider = provider->next;
  }

  if (path.empty())
    return false;

  AddToCache(key, path);

  *result = path;
  return true;
}

bool PathService::Override(int key, const FilePath& path) {
  PathData* path_data = GetPathData();
  DCHECK(path_data);
  DCHECK(key > base::DIR_CURRENT) << "invalid path key";

  FilePath file_path = path;

  // Make sure the directory exists. We need to do this before we translate
  // this to the absolute path because on POSIX, AbsolutePath fails if called
  // on a non-existant path.
  if (!file_util::PathExists(file_path) &&
      !file_util::CreateDirectory(file_path))
    return false;

  // We need to have an absolute path, as extensions and plugins don't like
  // relative paths, and will glady crash the browser in CHECK()s if they get a
  // relative path.
  if (!file_util::AbsolutePath(&file_path))
    return false;

  base::AutoLock scoped_lock(path_data->lock);

  // Clear the cache now. Some of its entries could have depended
  // on the value we are overriding, and are now out of sync with reality.
  path_data->cache.clear();

  path_data->cache[key] = file_path;
  path_data->overrides[key] = file_path;

  return true;
}

void PathService::RegisterProvider(ProviderFunc func, int key_start,
                                   int key_end) {
  PathData* path_data = GetPathData();
  DCHECK(path_data);
  DCHECK(key_end > key_start);

  base::AutoLock scoped_lock(path_data->lock);

  Provider* p;

#ifndef NDEBUG
  p = path_data->providers;
  while (p) {
    DCHECK(key_start >= p->key_end || key_end <= p->key_start) <<
      "path provider collision";
    p = p->next;
  }
#endif

  p = new Provider;
  p->is_static = false;
  p->func = func;
  p->next = path_data->providers;
#ifndef NDEBUG
  p->key_start = key_start;
  p->key_end = key_end;
#endif
  path_data->providers = p;
}
