// Copyright 2017 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/media/cdm_file_impl.h"

#include <set>
#include <utility>

#include "base/callback.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/task/post_task.h"
#include "storage/browser/fileapi/file_system_context.h"
#include "storage/browser/fileapi/file_system_operation_context.h"
#include "storage/browser/fileapi/file_system_url.h"
#include "storage/browser/quota/quota_manager.h"
#include "storage/common/fileapi/file_system_types.h"

namespace content {

namespace {

// The CDM interface has a restriction that file names can not begin with _,
// so use it to prefix temporary files.
const char kTemporaryFilePrefix[] = "_";

std::string GetTempFileName(const std::string& file_name) {
  DCHECK(!base::StartsWith(file_name, kTemporaryFilePrefix,
                           base::CompareCase::SENSITIVE));
  return kTemporaryFilePrefix + file_name;
}

// The file system is different for each CDM and each origin. So track files
// in use based on (file system ID, origin, file name).
struct FileLockKey {
  FileLockKey(const std::string& file_system_id,
              const url::Origin& origin,
              const std::string& file_name)
      : file_system_id(file_system_id), origin(origin), file_name(file_name) {}
  ~FileLockKey() = default;

  // Allow use as a key in std::set.
  bool operator<(const FileLockKey& other) const {
    return std::tie(file_system_id, origin, file_name) <
           std::tie(other.file_system_id, other.origin, other.file_name);
  }

  std::string file_system_id;
  url::Origin origin;
  std::string file_name;
};

// File map shared by all CdmFileImpl objects to prevent read/write race.
// A lock must be acquired before opening a file to ensure that the file is not
// currently in use. The lock must be held until the file is closed.
class FileLockMap {
 public:
  FileLockMap() = default;
  ~FileLockMap() = default;

  // Acquire a lock on the file represented by |key|. Returns true if |key|
  // is not currently in use, false otherwise.
  bool AcquireFileLock(const FileLockKey& key) {
    DVLOG(3) << __func__ << " file: " << key.file_name;
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    // Add a new entry. If |key| already has an entry, insert() tells so
    // with the second piece of the returned value and does not modify
    // the original.
    return file_lock_map_.insert(key).second;
  }

  // Tests whether a lock is held on |key| or not. Returns true if |key|
  // is currently locked, false otherwise.
  bool IsFileLockHeld(const FileLockKey& key) {
    DVLOG(3) << __func__ << " file: " << key.file_name;
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    // Lock is held if there is an entry for |key|.
    return file_lock_map_.count(key) > 0;
  }

  // Release the lock held on the file represented by |key|. If
  // |on_close_callback| has been set, run it before releasing the lock.
  void ReleaseFileLock(const FileLockKey& key) {
    DVLOG(3) << __func__ << " file: " << key.file_name;
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    auto entry = file_lock_map_.find(key);
    if (entry == file_lock_map_.end()) {
      NOTREACHED() << "Unable to release lock on file " << key.file_name;
      return;
    }

    file_lock_map_.erase(entry);
  }

 private:
  // Note that this map is never deleted. As entries are removed when a file
  // is closed, it should never get too large.
  std::set<FileLockKey> file_lock_map_;

  THREAD_CHECKER(thread_checker_);
  DISALLOW_COPY_AND_ASSIGN(FileLockMap);
};

// The FileLockMap is a global lock map shared by all CdmFileImpl instances.
FileLockMap* GetFileLockMap() {
  static auto* file_lock_map = new FileLockMap();
  return file_lock_map;
}

}  // namespace

CdmFileImpl::CdmFileImpl(
    const std::string& file_name,
    const url::Origin& origin,
    const std::string& file_system_id,
    const std::string& file_system_root_uri,
    scoped_refptr<storage::FileSystemContext> file_system_context)
    : file_name_(file_name),
      temp_file_name_(GetTempFileName(file_name_)),
      origin_(origin),
      file_system_id_(file_system_id),
      file_system_root_uri_(file_system_root_uri),
      file_system_context_(file_system_context),
      weak_factory_(this) {
  DVLOG(3) << __func__ << " " << file_name_;
}

CdmFileImpl::~CdmFileImpl() {
  DVLOG(3) << __func__ << " " << file_name_;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // If a file open was started but hasn't completed by now, run the callback
  // and report an error.
  if (pending_open_callback_) {
    std::move(pending_open_callback_)
        .Run(base::File(base::File::FILE_ERROR_ABORT));
  }

  if (lock_state_ == LockState::kFileAndTempFileLocked) {
    // Temporary file is open, so close and release it.
    if (temporary_file_on_close_callback_)
      std::move(temporary_file_on_close_callback_).Run();
    ReleaseFileLock(temp_file_name_);
  }
  if (lock_state_ != LockState::kNone) {
    // Original file is open, so close and release it.
    if (on_close_callback_)
      std::move(on_close_callback_).Run();
    ReleaseFileLock(file_name_);
  }
}

void CdmFileImpl::Initialize(OpenFileCallback callback) {
  DVLOG(3) << __func__ << " file: " << file_name_;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK_EQ(LockState::kNone, lock_state_);
  DCHECK(!pending_open_callback_);

  // Grab the lock on |file_name_|. The lock will be held until this object is
  // destructed.
  if (!AcquireFileLock(file_name_)) {
    DVLOG(3) << "File " << file_name_ << " is already in use.";
    std::move(callback).Run(base::File(base::File::FILE_ERROR_IN_USE));
    return;
  }

  // We have the lock on |file_name_|. Now open the file for reading. Since
  // we don't know if this file exists or not, provide FLAG_OPEN_ALWAYS to
  // create the file if it doesn't exist.
  lock_state_ = LockState::kFileLocked;
  pending_open_callback_ = std::move(callback);
  OpenFile(file_name_, base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ,
           base::BindOnce(&CdmFileImpl::OnFileOpenedForReading,
                          weak_factory_.GetWeakPtr()));
}

void CdmFileImpl::OpenFile(const std::string& file_name,
                           uint32_t file_flags,
                           CreateOrOpenCallback callback) {
  DVLOG(3) << __func__ << " file: " << file_name << ", flags: " << file_flags;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK_NE(LockState::kNone, lock_state_);
  DCHECK(IsFileLockHeld(file_name));
  DCHECK(pending_open_callback_);

  storage::FileSystemURL file_url = CreateFileSystemURL(file_name);
  storage::AsyncFileUtil* file_util = file_system_context_->GetAsyncFileUtil(
      storage::kFileSystemTypePluginPrivate);
  auto operation_context =
      std::make_unique<storage::FileSystemOperationContext>(
          file_system_context_.get());
  operation_context->set_allowed_bytes_growth(storage::QuotaManager::kNoLimit);
  DVLOG(3) << "Opening " << file_url.DebugString();

  file_util->CreateOrOpen(std::move(operation_context), file_url, file_flags,
                          std::move(callback));
}

void CdmFileImpl::OnFileOpenedForReading(base::File file,
                                         base::OnceClosure on_close_callback) {
  DVLOG(3) << __func__ << " file: " << file_name_;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK_EQ(LockState::kFileLocked, lock_state_);
  DCHECK(pending_open_callback_);

  if (!file.IsValid()) {
    // File is invalid. Note that the lock on |file_name_| is kept until this
    // object is destructed.
    DLOG(WARNING) << "Unable to open file " << file_name_ << ", error: "
                  << base::File::ErrorToString(file.error_details());
    std::move(pending_open_callback_).Run(std::move(file));
    return;
  }

  // When the file is closed, |on_close_callback| will be run.
  on_close_callback_ = std::move(on_close_callback);
  std::move(pending_open_callback_).Run(std::move(file));
}

void CdmFileImpl::OpenFileForWriting(OpenFileForWritingCallback callback) {
  DVLOG(3) << __func__ << " " << file_name_;

  // Fail if this is called out of order. We must have opened the original
  // file, and there should be no call in progress.
  if (lock_state_ != LockState::kFileLocked || pending_open_callback_) {
    std::move(callback).Run(
        base::File(base::File::FILE_ERROR_INVALID_OPERATION));
    return;
  }

  // Grab a lock on the temporary file. The lock will be held until this
  // new file is renamed in CommitWrite() (or this object is
  // destructed).
  if (!AcquireFileLock(temp_file_name_)) {
    DVLOG(3) << "File " << temp_file_name_ << " is already in use.";
    std::move(callback).Run(base::File(base::File::FILE_ERROR_IN_USE));
    return;
  }

  // We now have locks on both |file_name_| and |temp_file_name_|. Open the
  // temporary file for writing. Specifying FLAG_CREATE_ALWAYS which will
  // overwrite any existing file.
  lock_state_ = LockState::kFileAndTempFileLocked;
  pending_open_callback_ = std::move(callback);
  OpenFile(temp_file_name_,
           base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE,
           base::BindOnce(&CdmFileImpl::OnTempFileOpenedForWriting,
                          weak_factory_.GetWeakPtr()));
}

void CdmFileImpl::OnTempFileOpenedForWriting(
    base::File file,
    base::OnceClosure on_close_callback) {
  DVLOG(3) << __func__ << " file: " << file_name_;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK_EQ(LockState::kFileAndTempFileLocked, lock_state_);
  DCHECK(pending_open_callback_);

  if (!file.IsValid()) {
    DLOG(WARNING) << "Unable to open file " << temp_file_name_ << ", error: "
                  << base::File::ErrorToString(file.error_details());
    lock_state_ = LockState::kFileLocked;
    ReleaseFileLock(temp_file_name_);
    std::move(pending_open_callback_).Run(std::move(file));
    return;
  }

  temporary_file_on_close_callback_ = std::move(on_close_callback);
  std::move(pending_open_callback_).Run(std::move(file));
}

void CdmFileImpl::CommitWrite(CommitWriteCallback callback) {
  DVLOG(3) << __func__ << " " << temp_file_name_ << " to " << file_name_;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK_EQ(LockState::kFileAndTempFileLocked, lock_state_);
  DCHECK(IsFileLockHeld(file_name_));
  DCHECK(IsFileLockHeld(temp_file_name_));

  // TODO(jrummell): Verify that the written file does not exceed the file
  // size limit of 32MB. If it does simply delete the written file and fail.

  // Fail if this is called out of order. We must have opened both the original
  // and the temporary file, and there should be no call in progress.
  if (lock_state_ != LockState::kFileAndTempFileLocked ||
      pending_open_callback_) {
    std::move(callback).Run(
        base::File(base::File::FILE_ERROR_INVALID_OPERATION));
    return;
  }

  if (on_close_callback_)
    std::move(on_close_callback_).Run();
  if (temporary_file_on_close_callback_)
    std::move(temporary_file_on_close_callback_).Run();

  // OpenFile() will be called after the file is renamed, so save |callback|.
  pending_open_callback_ = std::move(callback);

  storage::FileSystemURL src_file_url = CreateFileSystemURL(temp_file_name_);
  storage::FileSystemURL dest_file_url = CreateFileSystemURL(file_name_);
  storage::AsyncFileUtil* file_util = file_system_context_->GetAsyncFileUtil(
      storage::kFileSystemTypePluginPrivate);
  auto operation_context =
      std::make_unique<storage::FileSystemOperationContext>(
          file_system_context_.get());
  DVLOG(3) << "Renaming " << src_file_url.DebugString() << " to "
           << dest_file_url.DebugString();
  file_util->MoveFileLocal(
      std::move(operation_context), src_file_url, dest_file_url,
      storage::FileSystemOperation::OPTION_NONE,
      base::BindOnce(&CdmFileImpl::OnFileRenamed, weak_factory_.GetWeakPtr()));
}

void CdmFileImpl::OnFileRenamed(base::File::Error move_result) {
  DVLOG(3) << __func__;
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  DCHECK_EQ(LockState::kFileAndTempFileLocked, lock_state_);
  DCHECK(pending_open_callback_);

  // Temporary file has been renamed, so we can release the lock on it.
  ReleaseFileLock(temp_file_name_);
  lock_state_ = LockState::kFileLocked;

  // Was the rename successful?
  if (move_result != base::File::FILE_OK) {
    std::move(pending_open_callback_).Run(base::File(move_result));
    return;
  }

  // Reopen the original file for reading. Specifying FLAG_OPEN as the file
  // has to exist or something's wrong.
  OpenFile(file_name_, base::File::FLAG_OPEN | base::File::FLAG_READ,
           base::BindOnce(&CdmFileImpl::OnFileOpenedForReading,
                          weak_factory_.GetWeakPtr()));
}

storage::FileSystemURL CdmFileImpl::CreateFileSystemURL(
    const std::string& file_name) {
  return file_system_context_->CrackURL(
      GURL(file_system_root_uri_ + file_name));
}

bool CdmFileImpl::AcquireFileLock(const std::string& file_name) {
  FileLockKey file_lock_key(file_system_id_, origin_, file_name);
  return GetFileLockMap()->AcquireFileLock(file_lock_key);
}

bool CdmFileImpl::IsFileLockHeld(const std::string& file_name) {
  FileLockKey file_lock_key(file_system_id_, origin_, file_name);
  return GetFileLockMap()->IsFileLockHeld(file_lock_key);
}

void CdmFileImpl::ReleaseFileLock(const std::string& file_name) {
  FileLockKey file_lock_key(file_system_id_, origin_, file_name);
  GetFileLockMap()->ReleaseFileLock(file_lock_key);
}

}  // namespace content
