// Copyright (c) 2013 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 "content/browser/gpu/shader_disk_cache.h"

#include "base/macros.h"
#include "base/threading/thread_checker.h"
#include "content/browser/gpu/gpu_process_host.h"
#include "content/public/browser/browser_thread.h"
#include "gpu/command_buffer/common/constants.h"
#include "net/base/cache_type.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"

namespace content {

namespace {

static const base::FilePath::CharType kGpuCachePath[] =
    FILE_PATH_LITERAL("GPUCache");

void EntryCloser(disk_cache::Entry* entry) {
  entry->Close();
}

void FreeDiskCacheIterator(
    std::unique_ptr<disk_cache::Backend::Iterator> iterator) {}

}  // namespace

// ShaderDiskCacheEntry handles the work of caching/updating the cached
// shaders.
class ShaderDiskCacheEntry
    : public base::ThreadChecker,
      public base::RefCounted<ShaderDiskCacheEntry> {
 public:
  ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache,
                       const std::string& key,
                       const std::string& shader);
  void Cache();

 private:
  friend class base::RefCounted<ShaderDiskCacheEntry>;

  enum OpType {
    TERMINATE,
    OPEN_ENTRY,
    WRITE_DATA,
    CREATE_ENTRY,
  };

  ~ShaderDiskCacheEntry();

  void OnOpComplete(int rv);

  int OpenCallback(int rv);
  int WriteCallback(int rv);
  int IOComplete(int rv);

  base::WeakPtr<ShaderDiskCache> cache_;
  OpType op_type_;
  std::string key_;
  std::string shader_;
  disk_cache::Entry* entry_;

  DISALLOW_COPY_AND_ASSIGN(ShaderDiskCacheEntry);
};

// ShaderDiskReadHelper is used to load all of the cached shaders from the
// disk cache and send to the memory cache.
class ShaderDiskReadHelper
    : public base::ThreadChecker,
      public base::RefCounted<ShaderDiskReadHelper> {
 public:
  ShaderDiskReadHelper(base::WeakPtr<ShaderDiskCache> cache, int host_id);
  void LoadCache();

 private:
  friend class base::RefCounted<ShaderDiskReadHelper>;

  enum OpType {
    TERMINATE,
    OPEN_NEXT,
    OPEN_NEXT_COMPLETE,
    READ_COMPLETE,
    ITERATION_FINISHED
  };


  ~ShaderDiskReadHelper();

  void OnOpComplete(int rv);

  int OpenNextEntry();
  int OpenNextEntryComplete(int rv);
  int ReadComplete(int rv);
  int IterationComplete(int rv);

  base::WeakPtr<ShaderDiskCache> cache_;
  OpType op_type_;
  std::unique_ptr<disk_cache::Backend::Iterator> iter_;
  scoped_refptr<net::IOBufferWithSize> buf_;
  int host_id_;
  disk_cache::Entry* entry_;

  DISALLOW_COPY_AND_ASSIGN(ShaderDiskReadHelper);
};

class ShaderClearHelper
    : public base::RefCounted<ShaderClearHelper>,
      public base::SupportsWeakPtr<ShaderClearHelper> {
 public:
  ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
                    const base::FilePath& path,
                    const base::Time& delete_begin,
                    const base::Time& delete_end,
                    const base::Closure& callback);
  void Clear();

 private:
  friend class base::RefCounted<ShaderClearHelper>;

  enum OpType {
    TERMINATE,
    VERIFY_CACHE_SETUP,
    DELETE_CACHE
  };

  ~ShaderClearHelper();

  void DoClearShaderCache(int rv);

  scoped_refptr<ShaderDiskCache> cache_;
  OpType op_type_;
  base::FilePath path_;
  base::Time delete_begin_;
  base::Time delete_end_;
  base::Closure callback_;

  DISALLOW_COPY_AND_ASSIGN(ShaderClearHelper);
};

ShaderDiskCacheEntry::ShaderDiskCacheEntry(base::WeakPtr<ShaderDiskCache> cache,
                                           const std::string& key,
                                           const std::string& shader)
  : cache_(cache),
    op_type_(OPEN_ENTRY),
    key_(key),
    shader_(shader),
    entry_(NULL) {
}

ShaderDiskCacheEntry::~ShaderDiskCacheEntry() {
  if (entry_)
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                            base::Bind(&EntryCloser, entry_));
}

void ShaderDiskCacheEntry::Cache() {
  DCHECK(CalledOnValidThread());
  if (!cache_.get())
    return;

  int rv = cache_->backend()->OpenEntry(
      key_,
      &entry_,
      base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this));
  if (rv != net::ERR_IO_PENDING)
    OnOpComplete(rv);
}

void ShaderDiskCacheEntry::OnOpComplete(int rv) {
  DCHECK(CalledOnValidThread());
  if (!cache_.get())
    return;

  do {
    switch (op_type_) {
      case OPEN_ENTRY:
        rv = OpenCallback(rv);
        break;
      case CREATE_ENTRY:
        rv = WriteCallback(rv);
        break;
      case WRITE_DATA:
        rv = IOComplete(rv);
        break;
      case TERMINATE:
        rv = net::ERR_IO_PENDING;  // break the loop.
        break;
      default:
        NOTREACHED();  // Invalid op_type_ provided.
        break;
    }
  } while (rv != net::ERR_IO_PENDING);
}

int ShaderDiskCacheEntry::OpenCallback(int rv) {
  DCHECK(CalledOnValidThread());
  // Called through OnOpComplete, so we know |cache_| is valid.
  if (rv == net::OK) {
    cache_->backend()->OnExternalCacheHit(key_);
    cache_->EntryComplete(this);
    op_type_ = TERMINATE;
    return rv;
  }

  op_type_ = CREATE_ENTRY;
  return cache_->backend()->CreateEntry(
      key_,
      &entry_,
      base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this));
}

int ShaderDiskCacheEntry::WriteCallback(int rv) {
  DCHECK(CalledOnValidThread());
  // Called through OnOpComplete, so we know |cache_| is valid.
  if (rv != net::OK) {
    LOG(ERROR) << "Failed to create shader cache entry: " << rv;
    cache_->EntryComplete(this);
    op_type_ = TERMINATE;
    return rv;
  }

  op_type_ = WRITE_DATA;
  scoped_refptr<net::StringIOBuffer> io_buf = new net::StringIOBuffer(shader_);
  return entry_->WriteData(
      1,
      0,
      io_buf.get(),
      shader_.length(),
      base::Bind(&ShaderDiskCacheEntry::OnOpComplete, this),
      false);
}

int ShaderDiskCacheEntry::IOComplete(int rv) {
  DCHECK(CalledOnValidThread());
  // Called through OnOpComplete, so we know |cache_| is valid.
  cache_->EntryComplete(this);
  op_type_ = TERMINATE;
  return rv;
}

ShaderDiskReadHelper::ShaderDiskReadHelper(
    base::WeakPtr<ShaderDiskCache> cache,
    int host_id)
    : cache_(cache),
      op_type_(OPEN_NEXT),
      buf_(NULL),
      host_id_(host_id),
      entry_(NULL) {
}

void ShaderDiskReadHelper::LoadCache() {
  DCHECK(CalledOnValidThread());
  if (!cache_.get())
    return;
  OnOpComplete(net::OK);
}

void ShaderDiskReadHelper::OnOpComplete(int rv) {
  DCHECK(CalledOnValidThread());
  if (!cache_.get())
    return;

  do {
    switch (op_type_) {
      case OPEN_NEXT:
        rv = OpenNextEntry();
        break;
      case OPEN_NEXT_COMPLETE:
        rv = OpenNextEntryComplete(rv);
        break;
      case READ_COMPLETE:
        rv = ReadComplete(rv);
        break;
      case ITERATION_FINISHED:
        rv = IterationComplete(rv);
        break;
      case TERMINATE:
        cache_->ReadComplete();
        rv = net::ERR_IO_PENDING;  // break the loop
        break;
      default:
        NOTREACHED();  // Invalid state for read helper
        rv = net::ERR_FAILED;
        break;
    }
  } while (rv != net::ERR_IO_PENDING);
}

int ShaderDiskReadHelper::OpenNextEntry() {
  DCHECK(CalledOnValidThread());
  // Called through OnOpComplete, so we know |cache_| is valid.
  op_type_ = OPEN_NEXT_COMPLETE;
  if (!iter_)
    iter_ = cache_->backend()->CreateIterator();
  return iter_->OpenNextEntry(
      &entry_, base::Bind(&ShaderDiskReadHelper::OnOpComplete, this));
}

int ShaderDiskReadHelper::OpenNextEntryComplete(int rv) {
  DCHECK(CalledOnValidThread());
  // Called through OnOpComplete, so we know |cache_| is valid.
  if (rv == net::ERR_FAILED) {
    iter_.reset();
    op_type_ = ITERATION_FINISHED;
    return net::OK;
  }

  if (rv < 0)
    return rv;

  op_type_ = READ_COMPLETE;
  buf_ = new net::IOBufferWithSize(entry_->GetDataSize(1));
  return entry_->ReadData(
      1,
      0,
      buf_.get(),
      buf_->size(),
      base::Bind(&ShaderDiskReadHelper::OnOpComplete, this));
}

int ShaderDiskReadHelper::ReadComplete(int rv) {
  DCHECK(CalledOnValidThread());
  // Called through OnOpComplete, so we know |cache_| is valid.
  if (rv && rv == buf_->size()) {
    GpuProcessHost* host = GpuProcessHost::FromID(host_id_);
    if (host)
      host->LoadedShader(entry_->GetKey(), std::string(buf_->data(),
                                                       buf_->size()));
  }

  buf_ = NULL;
  entry_->Close();
  entry_ = NULL;

  op_type_ = OPEN_NEXT;
  return net::OK;
}

int ShaderDiskReadHelper::IterationComplete(int rv) {
  DCHECK(CalledOnValidThread());
  // Called through OnOpComplete, so we know |cache_| is valid.
  iter_.reset();
  op_type_ = TERMINATE;
  return net::OK;
}

ShaderDiskReadHelper::~ShaderDiskReadHelper() {
  if (entry_) {
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                            base::Bind(&EntryCloser, entry_));
  }
  if (iter_) {
    BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
                            base::Bind(&FreeDiskCacheIterator,
                                       base::Passed(&iter_)));
  }
}

ShaderClearHelper::ShaderClearHelper(scoped_refptr<ShaderDiskCache> cache,
                    const base::FilePath& path,
                    const base::Time& delete_begin,
                    const base::Time& delete_end,
                    const base::Closure& callback)
    : cache_(cache),
      op_type_(VERIFY_CACHE_SETUP),
      path_(path),
      delete_begin_(delete_begin),
      delete_end_(delete_end),
      callback_(callback) {
}

ShaderClearHelper::~ShaderClearHelper() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
}

void ShaderClearHelper::Clear() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  DoClearShaderCache(net::OK);
}

void ShaderClearHelper::DoClearShaderCache(int rv) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  // Hold a ref to ourselves so when we do the CacheCleared call we don't get
  // auto-deleted when our ref count drops to zero.
  scoped_refptr<ShaderClearHelper> helper = this;

  while (rv != net::ERR_IO_PENDING) {
    switch (op_type_) {
      case VERIFY_CACHE_SETUP:
        rv = cache_->SetAvailableCallback(
            base::Bind(&ShaderClearHelper::DoClearShaderCache, AsWeakPtr()));
        op_type_ = DELETE_CACHE;
        break;
      case DELETE_CACHE:
        rv = cache_->Clear(
            delete_begin_, delete_end_,
            base::Bind(&ShaderClearHelper::DoClearShaderCache, AsWeakPtr()));
        op_type_ = TERMINATE;
        break;
      case TERMINATE:
        ShaderCacheFactory::GetInstance()->CacheCleared(path_);
        callback_.Run();
        rv = net::ERR_IO_PENDING;  // Break the loop.
        break;
      default:
        NOTREACHED();  // Invalid state provided.
        op_type_ = TERMINATE;
        break;
    }
  }
}

// static
ShaderCacheFactory* ShaderCacheFactory::GetInstance() {
  return base::Singleton<ShaderCacheFactory,
                         base::LeakySingletonTraits<ShaderCacheFactory>>::get();
}

ShaderCacheFactory::ShaderCacheFactory() {
}

ShaderCacheFactory::~ShaderCacheFactory() {
}

void ShaderCacheFactory::SetCacheInfo(int32_t client_id,
                                      const base::FilePath& path) {
  client_id_to_path_map_[client_id] = path;
}

void ShaderCacheFactory::RemoveCacheInfo(int32_t client_id) {
  client_id_to_path_map_.erase(client_id);
}

scoped_refptr<ShaderDiskCache> ShaderCacheFactory::Get(int32_t client_id) {
  ClientIdToPathMap::iterator iter =
      client_id_to_path_map_.find(client_id);
  if (iter == client_id_to_path_map_.end())
    return NULL;
  return ShaderCacheFactory::GetByPath(iter->second);
}

scoped_refptr<ShaderDiskCache> ShaderCacheFactory::GetByPath(
    const base::FilePath& path) {
  ShaderCacheMap::iterator iter = shader_cache_map_.find(path);
  if (iter != shader_cache_map_.end())
    return iter->second;

  ShaderDiskCache* cache = new ShaderDiskCache(path);
  cache->Init();
  return cache;
}

void ShaderCacheFactory::AddToCache(const base::FilePath& key,
                                    ShaderDiskCache* cache) {
  shader_cache_map_[key] = cache;
}

void ShaderCacheFactory::RemoveFromCache(const base::FilePath& key) {
  shader_cache_map_.erase(key);
}

void ShaderCacheFactory::ClearByPath(const base::FilePath& path,
                                     const base::Time& delete_begin,
                                     const base::Time& delete_end,
                                     const base::Closure& callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  DCHECK(!callback.is_null());

  scoped_refptr<ShaderClearHelper> helper = new ShaderClearHelper(
      GetByPath(path), path, delete_begin, delete_end, callback);

  // We could receive requests to clear the same path with different
  // begin/end times. So, we keep a list of requests. If we haven't seen this
  // path before we kick off the clear and add it to the list. If we have see it
  // already, then we already have a clear running. We add this clear to the
  // list and wait for any previous clears to finish.
  ShaderClearMap::iterator iter = shader_clear_map_.find(path);
  if (iter != shader_clear_map_.end()) {
    iter->second.push(helper);
    return;
  }

  shader_clear_map_.insert(
      std::pair<base::FilePath, ShaderClearQueue>(path, ShaderClearQueue()));
  shader_clear_map_[path].push(helper);
  helper->Clear();
}

void ShaderCacheFactory::CacheCleared(const base::FilePath& path) {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  ShaderClearMap::iterator iter = shader_clear_map_.find(path);
  if (iter == shader_clear_map_.end()) {
    LOG(ERROR) << "Completed clear but missing clear helper.";
    return;
  }

  iter->second.pop();

  // If there are remaining items in the list we trigger the Clear on the
  // next one.
  if (!iter->second.empty()) {
    iter->second.front()->Clear();
    return;
  }

  shader_clear_map_.erase(path);
}

ShaderDiskCache::ShaderDiskCache(const base::FilePath& cache_path)
    : cache_available_(false),
      host_id_(0),
      cache_path_(cache_path),
      is_initialized_(false) {
  ShaderCacheFactory::GetInstance()->AddToCache(cache_path_, this);
}

ShaderDiskCache::~ShaderDiskCache() {
  ShaderCacheFactory::GetInstance()->RemoveFromCache(cache_path_);
}

void ShaderDiskCache::Init() {
  if (is_initialized_) {
    NOTREACHED();  // can't initialize disk cache twice.
    return;
  }
  is_initialized_ = true;

  int rv = disk_cache::CreateCacheBackend(
      net::SHADER_CACHE,
      net::CACHE_BACKEND_DEFAULT,
      cache_path_.Append(kGpuCachePath),
      gpu::kDefaultMaxProgramCacheMemoryBytes,
      true,
      BrowserThread::GetMessageLoopProxyForThread(BrowserThread::CACHE).get(),
      NULL,
      &backend_,
      base::Bind(&ShaderDiskCache::CacheCreatedCallback, this));

  if (rv == net::OK)
    cache_available_ = true;
}

void ShaderDiskCache::Cache(const std::string& key, const std::string& shader) {
  if (!cache_available_)
    return;

  scoped_refptr<ShaderDiskCacheEntry> shim =
      new ShaderDiskCacheEntry(AsWeakPtr(), key, shader);
  shim->Cache();

  entry_map_[shim.get()] = shim;
}

int ShaderDiskCache::Clear(
    const base::Time begin_time, const base::Time end_time,
    const net::CompletionCallback& completion_callback) {
  int rv;
  if (begin_time.is_null()) {
    rv = backend_->DoomAllEntries(completion_callback);
  } else {
    rv = backend_->DoomEntriesBetween(begin_time, end_time,
                                      completion_callback);
  }
  return rv;
}

int32_t ShaderDiskCache::Size() {
  if (!cache_available_)
    return -1;
  return backend_->GetEntryCount();
}

int ShaderDiskCache::SetAvailableCallback(
    const net::CompletionCallback& callback) {
  if (cache_available_)
    return net::OK;
  available_callback_ = callback;
  return net::ERR_IO_PENDING;
}

void ShaderDiskCache::CacheCreatedCallback(int rv) {
  if (rv != net::OK) {
    LOG(ERROR) << "Shader Cache Creation failed: " << rv;
    return;
  }
  helper_ = new ShaderDiskReadHelper(AsWeakPtr(), host_id_);
  helper_->LoadCache();
}

void ShaderDiskCache::EntryComplete(void* entry) {
  entry_map_.erase(entry);

  if (entry_map_.empty() && !cache_complete_callback_.is_null())
    cache_complete_callback_.Run(net::OK);
}

void ShaderDiskCache::ReadComplete() {
  helper_ = NULL;

  // The cache is considered available after we have finished reading any
  // of the old cache values off disk. This prevents a potential race where we
  // are reading from disk and execute a cache clear at the same time.
  cache_available_ = true;
  if (!available_callback_.is_null()) {
    available_callback_.Run(net::OK);
    available_callback_.Reset();
  }
}

int ShaderDiskCache::SetCacheCompleteCallback(
    const net::CompletionCallback& callback) {
  if (entry_map_.empty()) {
    return net::OK;
  }
  cache_complete_callback_ = callback;
  return net::ERR_IO_PENDING;
}

}  // namespace content

