// 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.

#ifndef COMPONENTS_SAFE_BROWSING_BROWSER_THREAT_DETAILS_CACHE_H_
#define COMPONENTS_SAFE_BROWSING_BROWSER_THREAT_DETAILS_CACHE_H_

// A class that gets threat details from the HTTP Cache.
// An instance of this class is generated by ThreatDetails.

#include <string>
#include <vector>

#include "base/callback.h"
#include "base/containers/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "net/base/completion_callback.h"

namespace network {
class SimpleURLLoader;
class SharedURLLoaderFactory;
}

namespace safe_browsing {

// Maps a URL to its Resource.
typedef base::hash_map<
    std::string,
    std::unique_ptr<ClientSafeBrowsingReportRequest::Resource>>
    ResourceMap;

class ThreatDetailsCacheCollector
    : public base::RefCounted<ThreatDetailsCacheCollector> {
 public:
  ThreatDetailsCacheCollector();

  // We use |request_context_getter|, we modify |resources| and
  // |result|, and we call |callback|, so they must all remain alive
  // for the lifetime of this object.
  void StartCacheCollection(
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
      ResourceMap* resources,
      bool* result,
      const base::Closure& callback);

  // Returns whether or not StartCacheCollection has been called.
  bool HasStarted();

 protected:
  // Called after the request completes (either successfully or with failure).
  void OnURLLoaderComplete(std::unique_ptr<std::string> response_body);

 private:
  friend class base::RefCounted<ThreatDetailsCacheCollector>;

  ~ThreatDetailsCacheCollector();

  // Points to the url for which we are fetching the HTTP cache entry or
  // redirect chain.
  ResourceMap::iterator resources_it_;

  // Points to the resources_ map in the ThreatDetails.
  ResourceMap* resources_;

  // Points to the cache_result_ in the ThreatDetails.
  bool* result_;

  // Method we call when we are done. The caller must be alive for the
  // whole time, we are modifying its state (see above).
  base::Closure callback_;

  // Set to true as soon as StartCacheCollection is called.
  bool has_started_;

  // Used to get a pointer to the current URLLoaderFactory.
  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;

  // The current SimpleURLLoader.
  std::unique_ptr<network::SimpleURLLoader> current_load_;

  // Returns the resource from resources_ that corresponds to |url|
  ClientSafeBrowsingReportRequest::Resource* GetResource(const GURL& url);

  // Creates a new URLFetcher and starts it.
  void OpenEntry();

  // Read the HTTP response from |current_load_| and add it to |pb_resource|.
  void ReadResponse(ClientSafeBrowsingReportRequest::Resource* pb_resource);

  // Read the body |data| and add it to |pb_resource|.
  void ReadData(ClientSafeBrowsingReportRequest::Resource* pb_resource,
                const std::string& data);

  // Called when we are done.
  void AllDone(bool success);

  // Advances to the next entry in resources_it_.
  void AdvanceEntry();
};

}  // namespace safe_browsing

#endif  // COMPONENTS_SAFE_BROWSING_BROWSER_THREAT_DETAILS_CACHE_H_
