// Copyright 2014 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 "extensions/browser/content_verify_job.h"

#include <algorithm>

#include "base/metrics/histogram.h"
#include "base/stl_util.h"
#include "base/task_runner_util.h"
#include "base/timer/elapsed_timer.h"
#include "content/public/browser/browser_thread.h"
#include "crypto/secure_hash.h"
#include "crypto/sha2.h"
#include "extensions/browser/content_hash_reader.h"

namespace extensions {

namespace {

ContentVerifyJob::TestDelegate* g_test_delegate = NULL;

class ScopedElapsedTimer {
 public:
  ScopedElapsedTimer(base::TimeDelta* total) : total_(total) { DCHECK(total_); }

  ~ScopedElapsedTimer() { *total_ += timer.Elapsed(); }

 private:
  // Some total amount of time we should add our elapsed time to at
  // destruction.
  base::TimeDelta* total_;

  // A timer for how long this object has been alive.
  base::ElapsedTimer timer;
};

}  // namespace

ContentVerifyJob::ContentVerifyJob(ContentHashReader* hash_reader,
                                   const FailureCallback& failure_callback)
    : done_reading_(false),
      hashes_ready_(false),
      total_bytes_read_(0),
      current_block_(0),
      current_hash_byte_count_(0),
      hash_reader_(hash_reader),
      failure_callback_(failure_callback),
      failed_(false) {
  // It's ok for this object to be constructed on a different thread from where
  // it's used.
  thread_checker_.DetachFromThread();
}

ContentVerifyJob::~ContentVerifyJob() {
  UMA_HISTOGRAM_COUNTS("ExtensionContentVerifyJob.TimeSpentUS",
                       time_spent_.InMicroseconds());
}

void ContentVerifyJob::Start() {
  DCHECK(thread_checker_.CalledOnValidThread());
  base::PostTaskAndReplyWithResult(
      content::BrowserThread::GetBlockingPool(),
      FROM_HERE,
      base::Bind(&ContentHashReader::Init, hash_reader_),
      base::Bind(&ContentVerifyJob::OnHashesReady, this));
}

void ContentVerifyJob::BytesRead(int count, const char* data) {
  ScopedElapsedTimer timer(&time_spent_);
  DCHECK(thread_checker_.CalledOnValidThread());
  if (failed_)
    return;
  if (g_test_delegate) {
    FailureReason reason =
        g_test_delegate->BytesRead(hash_reader_->extension_id(), count, data);
    if (reason != NONE)
      return DispatchFailureCallback(reason);
  }
  if (!hashes_ready_) {
    queue_.append(data, count);
    return;
  }
  DCHECK_GE(count, 0);
  int bytes_added = 0;

  while (bytes_added < count) {
    if (current_block_ >= hash_reader_->block_count())
      return DispatchFailureCallback(HASH_MISMATCH);

    if (!current_hash_.get()) {
      current_hash_byte_count_ = 0;
      current_hash_.reset(
          crypto::SecureHash::Create(crypto::SecureHash::SHA256));
    }
    // Compute how many bytes we should hash, and add them to the current hash.
    int bytes_to_hash =
        std::min(hash_reader_->block_size() - current_hash_byte_count_,
                 count - bytes_added);
    DCHECK(bytes_to_hash > 0);
    current_hash_->Update(data + bytes_added, bytes_to_hash);
    bytes_added += bytes_to_hash;
    current_hash_byte_count_ += bytes_to_hash;
    total_bytes_read_ += bytes_to_hash;

    // If we finished reading a block worth of data, finish computing the hash
    // for it and make sure the expected hash matches.
    if (current_hash_byte_count_ == hash_reader_->block_size() &&
        !FinishBlock()) {
      DispatchFailureCallback(HASH_MISMATCH);
      return;
    }
  }
}

void ContentVerifyJob::DoneReading() {
  ScopedElapsedTimer timer(&time_spent_);
  DCHECK(thread_checker_.CalledOnValidThread());
  if (failed_)
    return;
  if (g_test_delegate) {
    FailureReason reason =
        g_test_delegate->DoneReading(hash_reader_->extension_id());
    if (reason != NONE) {
      DispatchFailureCallback(reason);
      return;
    }
  }
  done_reading_ = true;
  if (hashes_ready_ && !FinishBlock())
    DispatchFailureCallback(HASH_MISMATCH);
}

bool ContentVerifyJob::FinishBlock() {
  if (current_hash_byte_count_ <= 0)
    return true;
  std::string final(crypto::kSHA256Length, 0);
  current_hash_->Finish(string_as_array(&final), final.size());
  current_hash_.reset();
  current_hash_byte_count_ = 0;

  int block = current_block_++;

  const std::string* expected_hash = NULL;
  if (!hash_reader_->GetHashForBlock(block, &expected_hash) ||
      *expected_hash != final)
    return false;

  return true;
}

void ContentVerifyJob::OnHashesReady(bool success) {
  if (!success && !g_test_delegate) {
    if (!hash_reader_->content_exists()) {
      // Ignore verification of non-existent resources.
      return;
    } else if (hash_reader_->have_verified_contents() &&
               hash_reader_->have_computed_hashes()) {
      DispatchFailureCallback(NO_HASHES_FOR_FILE);
    } else {
      DispatchFailureCallback(MISSING_ALL_HASHES);
    }
    return;
  }

  hashes_ready_ = true;
  if (!queue_.empty()) {
    std::string tmp;
    queue_.swap(tmp);
    BytesRead(tmp.size(), string_as_array(&tmp));
  }
  if (done_reading_) {
    ScopedElapsedTimer timer(&time_spent_);
    if (!FinishBlock())
      DispatchFailureCallback(HASH_MISMATCH);
  }
}

// static
void ContentVerifyJob::SetDelegateForTests(TestDelegate* delegate) {
  g_test_delegate = delegate;
}

void ContentVerifyJob::DispatchFailureCallback(FailureReason reason) {
  DCHECK(!failed_);
  failed_ = true;
  if (!failure_callback_.is_null()) {
    VLOG(1) << "job failed for " << hash_reader_->extension_id() << " "
            << hash_reader_->relative_path().MaybeAsASCII()
            << " reason:" << reason;
    failure_callback_.Run(reason);
    failure_callback_.Reset();
  }
}

}  // namespace extensions
