// 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_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);

  if (file.IsValid()) {
    int64_t len = file.GetLength();
    if (len >= static_cast<int64_t>(crypto::kSHA256Length) &&
        len <= static_cast<int64_t>(kMaxPpdSizeBytes) +
                   static_cast<int64_t>(crypto::kSHA256Length)) {
      std::unique_ptr<char[]> buf(new char[len]);
      if (file.ReadAtCurrentPos(buf.get(), len) == len) {
        base::StringPiece contents(buf.get(), len - crypto::kSHA256Length);
        base::StringPiece checksum(buf.get() + len - crypto::kSHA256Length,
                                   crypto::kSHA256Length);
        if (crypto::SHA256HashString(contents) == checksum) {
          base::File::Info info;
          if (file.GetInfo(&info)) {
            result.success = true;
            result.age = base::Time::Now() - info.last_modified;
            contents.CopyToString(&result.contents);
          }
        } else {
          LOG(ERROR) << "Bad checksum for cache key " << key;
        }
      }
    }
  }

  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::CreateSequencedTaskRunner(
          {base::ThreadPool(), base::TaskPriority::USER_VISIBLE,
           base::MayBlock(), base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN}),
      base::CreateSequencedTaskRunner(
          {base::ThreadPool(), 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
