/*
 *  Copyright 2004 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <time.h>

#if defined(WEBRTC_WIN)
#include "webrtc/base/win32.h"
#endif

#include <algorithm>
#include "webrtc/base/common.h"
#include "webrtc/base/diskcache.h"
#include "webrtc/base/fileutils.h"
#include "webrtc/base/pathutils.h"
#include "webrtc/base/stream.h"
#include "webrtc/base/stringencode.h"
#include "webrtc/base/stringutils.h"

#ifdef _DEBUG
#define TRANSPARENT_CACHE_NAMES 1
#else  // !_DEBUG
#define TRANSPARENT_CACHE_NAMES 0
#endif  // !_DEBUG

namespace rtc {

class DiskCache;

///////////////////////////////////////////////////////////////////////////////
// DiskCacheAdapter
///////////////////////////////////////////////////////////////////////////////

class DiskCacheAdapter : public StreamAdapterInterface {
public:
  DiskCacheAdapter(const DiskCache* cache, const std::string& id, size_t index,
                   StreamInterface* stream)
  : StreamAdapterInterface(stream), cache_(cache), id_(id), index_(index)
  { }
  ~DiskCacheAdapter() override {
    Close();
    cache_->ReleaseResource(id_, index_);
  }

private:
  const DiskCache* cache_;
  std::string id_;
  size_t index_;
};

///////////////////////////////////////////////////////////////////////////////
// DiskCache
///////////////////////////////////////////////////////////////////////////////

DiskCache::DiskCache() : max_cache_(0), total_size_(0), total_accessors_(0) {
}

DiskCache::~DiskCache() {
  ASSERT(0 == total_accessors_);
}

bool DiskCache::Initialize(const std::string& folder, size_t size) {
  if (!folder_.empty() || !Filesystem::CreateFolder(folder))
    return false;

  folder_ = folder;
  max_cache_ = size;
  ASSERT(0 == total_size_);

  if (!InitializeEntries())
    return false;

  return CheckLimit();
}

bool DiskCache::Purge() {
  if (folder_.empty())
    return false;

  if (total_accessors_ > 0) {
    LOG_F(LS_WARNING) << "Cache files open";
    return false;
  }

  if (!PurgeFiles())
    return false;

  map_.clear();
  return true;
}

bool DiskCache::LockResource(const std::string& id) {
  Entry* entry = GetOrCreateEntry(id, true);
  if (LS_LOCKED == entry->lock_state)
    return false;
  if ((LS_UNLOCKED == entry->lock_state) && (entry->accessors > 0))
    return false;
  if ((total_size_ > max_cache_) && !CheckLimit()) {
    LOG_F(LS_WARNING) << "Cache overfull";
    return false;
  }
  entry->lock_state = LS_LOCKED;
  return true;
}

StreamInterface* DiskCache::WriteResource(const std::string& id, size_t index) {
  Entry* entry = GetOrCreateEntry(id, false);
  if (LS_LOCKED != entry->lock_state)
    return NULL;

  size_t previous_size = 0;
  std::string filename(IdToFilename(id, index));
  FileStream::GetSize(filename, &previous_size);
  ASSERT(previous_size <= entry->size);
  if (previous_size > entry->size) {
    previous_size = entry->size;
  }

  scoped_ptr<FileStream> file(new FileStream);
  if (!file->Open(filename, "wb", NULL)) {
    LOG_F(LS_ERROR) << "Couldn't create cache file";
    return NULL;
  }

  entry->streams = std::max(entry->streams, index + 1);
  entry->size -= previous_size;
  total_size_ -= previous_size;

  entry->accessors += 1;
  total_accessors_ += 1;
  return new DiskCacheAdapter(this, id, index, file.release());
}

bool DiskCache::UnlockResource(const std::string& id) {
  Entry* entry = GetOrCreateEntry(id, false);
  if (LS_LOCKED != entry->lock_state)
    return false;

  if (entry->accessors > 0) {
    entry->lock_state = LS_UNLOCKING;
  } else {
    entry->lock_state = LS_UNLOCKED;
    entry->last_modified = time(0);
    CheckLimit();
  }
  return true;
}

StreamInterface* DiskCache::ReadResource(const std::string& id,
                                         size_t index) const {
  const Entry* entry = GetEntry(id);
  if (LS_UNLOCKED != entry->lock_state)
    return NULL;
  if (index >= entry->streams)
    return NULL;

  scoped_ptr<FileStream> file(new FileStream);
  if (!file->Open(IdToFilename(id, index), "rb", NULL))
    return NULL;

  entry->accessors += 1;
  total_accessors_ += 1;
  return new DiskCacheAdapter(this, id, index, file.release());
}

bool DiskCache::HasResource(const std::string& id) const {
  const Entry* entry = GetEntry(id);
  return (NULL != entry) && (entry->streams > 0);
}

bool DiskCache::HasResourceStream(const std::string& id, size_t index) const {
  const Entry* entry = GetEntry(id);
  if ((NULL == entry) || (index >= entry->streams))
    return false;

  std::string filename = IdToFilename(id, index);

  return FileExists(filename);
}

bool DiskCache::DeleteResource(const std::string& id) {
  Entry* entry = GetOrCreateEntry(id, false);
  if (!entry)
    return true;

  if ((LS_UNLOCKED != entry->lock_state) || (entry->accessors > 0))
    return false;

  bool success = true;
  for (size_t index = 0; index < entry->streams; ++index) {
    std::string filename = IdToFilename(id, index);

    if (!FileExists(filename))
      continue;

    if (!DeleteFile(filename)) {
      LOG_F(LS_ERROR) << "Couldn't remove cache file: " << filename;
      success = false;
    }
  }

  total_size_ -= entry->size;
  map_.erase(id);
  return success;
}

bool DiskCache::CheckLimit() {
#ifdef _DEBUG
  // Temporary check to make sure everything is working correctly.
  size_t cache_size = 0;
  for (EntryMap::iterator it = map_.begin(); it != map_.end(); ++it) {
    cache_size += it->second.size;
  }
  ASSERT(cache_size == total_size_);
#endif  // _DEBUG

  // TODO: Replace this with a non-brain-dead algorithm for clearing out the
  // oldest resources... something that isn't O(n^2)
  while (total_size_ > max_cache_) {
    EntryMap::iterator oldest = map_.end();
    for (EntryMap::iterator it = map_.begin(); it != map_.end(); ++it) {
      if ((LS_UNLOCKED != it->second.lock_state) || (it->second.accessors > 0))
        continue;
      oldest = it;
      break;
    }
    if (oldest == map_.end()) {
      LOG_F(LS_WARNING) << "All resources are locked!";
      return false;
    }
    for (EntryMap::iterator it = oldest++; it != map_.end(); ++it) {
      if (it->second.last_modified < oldest->second.last_modified) {
        oldest = it;
      }
    }
    if (!DeleteResource(oldest->first)) {
      LOG_F(LS_ERROR) << "Couldn't delete from cache!";
      return false;
    }
  }
  return true;
}

std::string DiskCache::IdToFilename(const std::string& id, size_t index) const {
#ifdef TRANSPARENT_CACHE_NAMES
  // This escapes colons and other filesystem characters, so the user can't open
  // special devices (like "COM1:"), or access other directories.
  size_t buffer_size = id.length()*3 + 1;
  char* buffer = new char[buffer_size];
  encode(buffer, buffer_size, id.data(), id.length(),
         unsafe_filename_characters(), '%');
  // TODO: ASSERT(strlen(buffer) < FileSystem::MaxBasenameLength());
#else  // !TRANSPARENT_CACHE_NAMES
  // We might want to just use a hash of the filename at some point, both for
  // obfuscation, and to avoid both filename length and escaping issues.
  ASSERT(false);
#endif  // !TRANSPARENT_CACHE_NAMES

  char extension[32];
  sprintfn(extension, ARRAY_SIZE(extension), ".%u", index);

  Pathname pathname;
  pathname.SetFolder(folder_);
  pathname.SetBasename(buffer);
  pathname.SetExtension(extension);

#ifdef TRANSPARENT_CACHE_NAMES
  delete [] buffer;
#endif  // TRANSPARENT_CACHE_NAMES

  return pathname.pathname();
}

bool DiskCache::FilenameToId(const std::string& filename, std::string* id,
                             size_t* index) const {
  Pathname pathname(filename);
  unsigned tempdex;
  if (1 != sscanf(pathname.extension().c_str(), ".%u", &tempdex))
    return false;

  *index = static_cast<size_t>(tempdex);

  size_t buffer_size = pathname.basename().length() + 1;
  char* buffer = new char[buffer_size];
  decode(buffer, buffer_size, pathname.basename().data(),
         pathname.basename().length(), '%');
  id->assign(buffer);
  delete [] buffer;
  return true;
}

DiskCache::Entry* DiskCache::GetOrCreateEntry(const std::string& id,
                                              bool create) {
  EntryMap::iterator it = map_.find(id);
  if (it != map_.end())
    return &it->second;
  if (!create)
    return NULL;
  Entry e;
  e.lock_state = LS_UNLOCKED;
  e.accessors = 0;
  e.size = 0;
  e.streams = 0;
  e.last_modified = time(0);
  it = map_.insert(EntryMap::value_type(id, e)).first;
  return &it->second;
}

void DiskCache::ReleaseResource(const std::string& id, size_t index) const {
  const Entry* entry = GetEntry(id);
  if (!entry) {
    LOG_F(LS_WARNING) << "Missing cache entry";
    ASSERT(false);
    return;
  }

  entry->accessors -= 1;
  total_accessors_ -= 1;

  if (LS_UNLOCKED != entry->lock_state) {
    // This is safe, because locked resources only issue WriteResource, which
    // is non-const.  Think about a better way to handle it.
    DiskCache* this2 = const_cast<DiskCache*>(this);
    Entry* entry2 = this2->GetOrCreateEntry(id, false);

    size_t new_size = 0;
    std::string filename(IdToFilename(id, index));
    FileStream::GetSize(filename, &new_size);
    entry2->size += new_size;
    this2->total_size_ += new_size;

    if ((LS_UNLOCKING == entry->lock_state) && (0 == entry->accessors)) {
      entry2->last_modified = time(0);
      entry2->lock_state = LS_UNLOCKED;
      this2->CheckLimit();
    }
  }
}

///////////////////////////////////////////////////////////////////////////////

} // namespace rtc
