// Copyright 2016 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 "chromeos/printing/ppd_cache.h"

#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/files/file_util.h"
#include "base/json/json_parser.h"
#include "base/json/json_writer.h"
#include "base/memory/ptr_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/synchronization/lock.h"
#include "base/task/post_task.h"
#include "base/task/thread_pool.h"
#include "base/task_runner_util.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/sequenced_task_runner_handle.h"
#include "base/time/time.h"
#include "base/values.h"
#include "chromeos/printing/printing_constants.h"
#include "crypto/sha2.h"
#include "net/base/io_buffer.h"
#include "net/filter/gzip_header.h"

namespace chromeos {
namespace {

// Return the (full) path to the file we expect to find the given key at.
base::FilePath FilePathForKey(const base::FilePath& base_dir,
                              const std::string& key) {
  std::string hashed_key = crypto::SHA256HashString(key);
  return base_dir.Append(base::HexEncode(hashed_key.data(), hashed_key.size()));
}

// If the cache doesn't already exist, create it.
void MaybeCreateCache(const base::FilePath& base_dir) {
  if (!base::PathExists(base_dir)) {
    base::CreateDirectory(base_dir);
  }
}

// Find implementation, blocks on file access.  Must be run on a thread that
// allows I/O.
PpdCache::FindResult FindImpl(const base::FilePath& cache_dir,
                              const std::string& key) {
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);

  PpdCache::FindResult result;
  result.success = false;
  if (!base::PathExists(cache_dir)) {
    // If the cache dir was missing, we'll miss anyway.
    return result;
  }

  base::File file(FilePathForKey(cache_dir, key),
                  base::File::FLAG_OPEN | base::File::FLAG_READ);

  base::File::Info info;
  if (!file.IsValid() || !file.GetInfo(&info))
    return result;

  if (info.size < static_cast<int64_t>(crypto::kSHA256Length) ||
      info.size > static_cast<int64_t>(kMaxPpdSizeBytes) +
                      static_cast<int64_t>(crypto::kSHA256Length)) {
    return result;
  }

  std::vector<char> buf(info.size);
  if (file.ReadAtCurrentPos(buf.data(), info.size) != info.size)
    return result;

  base::StringPiece contents(buf.data(), info.size - crypto::kSHA256Length);
  base::StringPiece checksum(buf.data() + info.size - crypto::kSHA256Length,
                             crypto::kSHA256Length);
  if (crypto::SHA256HashString(contents) != checksum) {
    LOG(ERROR) << "Bad checksum for cache key " << key;
    return result;
  }

  result.success = true;
  result.age = base::Time::Now() - info.last_modified;
  result.contents = std::string(contents);
  return result;
}

// Store implementation, blocks on file access.  Must be run on a thread that
// allows I/O.  If |age| is non-zero, explicitly set the age of the resulting
// file to be |age| before Now.
void StoreImpl(const base::FilePath& cache_dir,
               const std::string& key,
               const std::string& contents,
               base::TimeDelta age) {
  base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
                                                base::BlockingType::MAY_BLOCK);
  MaybeCreateCache(cache_dir);
  if (contents.size() > kMaxPpdSizeBytes) {
    LOG(ERROR) << "Ignoring attempt to cache large object";
  } else {
    auto path = FilePathForKey(cache_dir, key);
    base::File file(path,
                    base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
    std::string checksum = crypto::SHA256HashString(contents);
    if (!file.IsValid() ||
        file.WriteAtCurrentPos(contents.data(), contents.size()) !=
            static_cast<int>(contents.size()) ||
        file.WriteAtCurrentPos(checksum.data(), checksum.size()) !=
            static_cast<int>(checksum.size())) {
      LOG(ERROR) << "Failed to create ppd cache file";
      file.Close();
      if (!base::DeleteFile(path, false)) {
        LOG(ERROR) << "Failed to cleanup failed creation.";
      }
    } else {
      // Successfully wrote the file, adjust the age if requested.
      if (!age.is_zero()) {
        base::Time mod_time = base::Time::Now() - age;
        file.SetTimes(mod_time, mod_time);
      }
    }
  }
}

// Implementation of the PpdCache that uses two separate task runners for Store
// and Fetch since the two operations have different priorities. Note that the
// two operations are not sequenced so there should be no expectation that a
// call to Find will return a file that was previously Stored until the Store
// callback is run.
class PpdCacheImpl : public PpdCache {
 public:
  explicit PpdCacheImpl(
      const base::FilePath& cache_base_dir,
      scoped_refptr<base::SequencedTaskRunner> fetch_task_runner,
      scoped_refptr<base::SequencedTaskRunner> store_task_runner)
      : cache_base_dir_(cache_base_dir),
        fetch_task_runner_(std::move(fetch_task_runner)),
        store_task_runner_(std::move(store_task_runner)) {}

  // Public API functions.
  void Find(const std::string& key, FindCallback cb) override {
    base::PostTaskAndReplyWithResult(
        fetch_task_runner_.get(), FROM_HERE,
        base::BindOnce(&FindImpl, cache_base_dir_, key), std::move(cb));
  }

  // Store the given contents at the given key.  If cb is non-null, it will
  // be invoked on completion.
  void Store(const std::string& key, const std::string& contents) override {
    store_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&StoreImpl, cache_base_dir_, key, contents,
                                  base::TimeDelta()));
  }

  void StoreForTesting(const std::string& key,
                       const std::string& contents,
                       base::TimeDelta age) override {
    store_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(&StoreImpl, cache_base_dir_, key, contents, age));
  }

 private:
  ~PpdCacheImpl() override = default;

  base::FilePath cache_base_dir_;
  scoped_refptr<base::SequencedTaskRunner> fetch_task_runner_;
  scoped_refptr<base::SequencedTaskRunner> store_task_runner_;

  DISALLOW_COPY_AND_ASSIGN(PpdCacheImpl);
};

}  // namespace

// static
scoped_refptr<PpdCache> PpdCache::Create(const base::FilePath& cache_base_dir) {
  return scoped_refptr<PpdCache>(
      new PpdCacheImpl(cache_base_dir,
                       base::ThreadPool::CreateSequencedTaskRunner(
                           {base::TaskPriority::USER_VISIBLE, base::MayBlock(),
                            base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}),
                       base::ThreadPool::CreateSequencedTaskRunner(
                           {base::TaskPriority::BEST_EFFORT, base::MayBlock(),
                            base::TaskShutdownBehavior::BLOCK_SHUTDOWN})));
}

scoped_refptr<PpdCache> PpdCache::CreateForTesting(
    const base::FilePath& cache_base_dir,
    scoped_refptr<base::SequencedTaskRunner> io_task_runner) {
  return scoped_refptr<PpdCache>(
      new PpdCacheImpl(cache_base_dir, io_task_runner, io_task_runner));
}

}  // namespace chromeos
