// Copyright (c) 2012 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.
//
// Implementation of the MalwareDetails class.

#include "chrome/browser/safe_browsing/malware_details.h"

#include "base/bind.h"
#include "base/lazy_instance.h"
#include "base/md5.h"
#include "base/strings/string_util.h"
#include "chrome/browser/net/chrome_url_request_context_getter.h"
#include "chrome/browser/safe_browsing/malware_details_cache.h"
#include "chrome/browser/safe_browsing/report.pb.h"
#include "chrome/browser/safe_browsing/safe_browsing_service.h"
#include "content/public/browser/browser_thread.h"
#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h"

using content::BrowserThread;
using safe_browsing::ClientMalwareReportRequest;

// Only send small files for now, a better strategy would use the size
// of the whole report and the user's bandwidth.
static const uint32 kMaxBodySizeBytes = 1024;

MalwareDetailsCacheCollector::MalwareDetailsCacheCollector()
    : resources_(NULL), result_(NULL), has_started_(false) {}

void MalwareDetailsCacheCollector::StartCacheCollection(
    net::URLRequestContextGetter* request_context_getter,
    safe_browsing::ResourceMap* resources,
    bool* result,
    const base::Closure& callback) {
  // Start the data collection from the HTTP cache. We use a URLFetcher
  // and set the right flags so we only hit the cache.
  DVLOG(1) << "Getting cache data for all urls...";
  request_context_getter_ = request_context_getter;
  resources_ = resources;
  resources_it_ = resources_->begin();
  result_ = result;
  callback_ = callback;
  has_started_ = true;

  // Post a task in the message loop, so the callers don't need to
  // check if we call their callback immediately.
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&MalwareDetailsCacheCollector::OpenEntry, this));
}

bool MalwareDetailsCacheCollector::HasStarted() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  return has_started_;
}

MalwareDetailsCacheCollector::~MalwareDetailsCacheCollector() {}

// Fetch a URL and advance to the next one when done.
void MalwareDetailsCacheCollector::OpenEntry() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  DVLOG(1) << "OpenEntry";

  if (resources_it_ == resources_->end()) {
    AllDone(true);
    return;
  }

  if (!request_context_getter_.get()) {
    DVLOG(1) << "Missing request context getter";
    AllDone(false);
    return;
  }

  current_fetch_.reset(net::URLFetcher::Create(
      GURL(resources_it_->first), net::URLFetcher::GET, this));
  current_fetch_->SetRequestContext(request_context_getter_.get());
  // Only from cache, and don't save cookies.
  current_fetch_->SetLoadFlags(net::LOAD_ONLY_FROM_CACHE |
                               net::LOAD_DO_NOT_SAVE_COOKIES);
  current_fetch_->SetAutomaticallyRetryOn5xx(false);  // No retries.
  current_fetch_->Start();  // OnURLFetchComplete will be called when done.
}

ClientMalwareReportRequest::Resource* MalwareDetailsCacheCollector::GetResource(
    const GURL& url) {
  safe_browsing::ResourceMap::iterator it = resources_->find(url.spec());
  if (it != resources_->end()) {
    return it->second.get();
  }
  return NULL;
}

void MalwareDetailsCacheCollector::OnURLFetchComplete(
    const net::URLFetcher* source) {
  DVLOG(1) << "OnUrlFetchComplete";
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  DCHECK(current_fetch_.get());
  if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS &&
      source->GetStatus().error() == net::ERR_CACHE_MISS) {
    // Cache miss, skip this resource.
    DVLOG(1) << "Cache miss for url: " << source->GetURL();
    AdvanceEntry();
    return;
  }

  if (source->GetStatus().status() != net::URLRequestStatus::SUCCESS) {
    // Some other error occurred, e.g. the request could have been cancelled.
    DVLOG(1) << "Unsuccessful fetch: " << source->GetURL();
    AdvanceEntry();
    return;
  }

  // Set the response headers and body to the right resource, which
  // might not be the same as the one we asked for.
  // For redirects, resources_it_->first != url.spec().
  ClientMalwareReportRequest::Resource* resource =
      GetResource(source->GetURL());
  if (!resource) {
    DVLOG(1) << "Cannot find resource for url:" << source->GetURL();
    AdvanceEntry();
    return;
  }

  ReadResponse(resource, source);
  std::string data;
  source->GetResponseAsString(&data);
  ReadData(resource, data);
  AdvanceEntry();
}

void MalwareDetailsCacheCollector::ReadResponse(
    ClientMalwareReportRequest::Resource* pb_resource,
    const net::URLFetcher* source) {
  DVLOG(1) << "ReadResponse";
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  net::HttpResponseHeaders* headers = source->GetResponseHeaders();
  if (!headers) {
    DVLOG(1) << "Missing response headers.";
    return;
  }

  ClientMalwareReportRequest::HTTPResponse* pb_response =
      pb_resource->mutable_response();
  pb_response->mutable_firstline()->set_code(headers->response_code());
  void* iter = NULL;
  std::string name, value;
  while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
    ClientMalwareReportRequest::HTTPHeader* pb_header =
        pb_response->add_headers();
    pb_header->set_name(name);
    // Strip any Set-Cookie headers.
    if (LowerCaseEqualsASCII(name, "set-cookie")) {
      pb_header->set_value("");
    } else {
      pb_header->set_value(value);
    }
  }

  if (!source->WasFetchedViaProxy()) {
    pb_response->set_remote_ip(source->GetSocketAddress().ToString());
  }
}

void MalwareDetailsCacheCollector::ReadData(
    ClientMalwareReportRequest::Resource* pb_resource,
    const std::string& data) {
  DVLOG(1) << "ReadData";
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  ClientMalwareReportRequest::HTTPResponse* pb_response =
      pb_resource->mutable_response();
  if (data.size() <= kMaxBodySizeBytes) {  // Only send small bodies for now.
    pb_response->set_body(data);
  }
  pb_response->set_bodylength(data.size());
  base::MD5Digest digest;
  base::MD5Sum(data.c_str(), data.size(), &digest);
  pb_response->set_bodydigest(base::MD5DigestToBase16(digest));
}

void MalwareDetailsCacheCollector::AdvanceEntry() {
  DVLOG(1) << "AdvanceEntry";
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  // Advance to the next resource.
  ++resources_it_;
  current_fetch_.reset(NULL);

  // Create a task so we don't take over the IO thread for too long.
  BrowserThread::PostTask(
      BrowserThread::IO, FROM_HERE,
      base::Bind(&MalwareDetailsCacheCollector::OpenEntry, this));
}

void MalwareDetailsCacheCollector::AllDone(bool success) {
  DVLOG(1) << "AllDone";
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  *result_ = success;
  BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, callback_);
  callback_.Reset();
}
