// 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 NET_URL_REQUEST_URL_REQUEST_JOB_MANAGER_H_
#define NET_URL_REQUEST_URL_REQUEST_JOB_MANAGER_H_

#include <map>
#include <string>
#include <vector>

#include "base/synchronization/lock.h"
#include "base/threading/platform_thread.h"
#include "net/url_request/url_request.h"

template <typename T> struct DefaultSingletonTraits;

namespace net {

// This class is responsible for managing the set of protocol factories and
// request interceptors that determine how an URLRequestJob gets created to
// handle an URLRequest.
//
// MULTI-THREADING NOTICE:
//   URLRequest is designed to have all consumers on a single thread, and
//   so no attempt is made to support ProtocolFactory or Interceptor instances
//   being registered/unregistered or in any way poked on multiple threads.
//   However, we do support checking for supported schemes FROM ANY THREAD
//   (i.e., it is safe to call SupportsScheme on any thread).
//
class URLRequestJobManager {
 public:
  // Returns the singleton instance.
  static URLRequestJobManager* GetInstance();

  // Instantiate an URLRequestJob implementation based on the registered
  // interceptors and protocol factories.  This will always succeed in
  // returning a job unless we are--in the extreme case--out of memory.
  URLRequestJob* CreateJob(URLRequest* request,
                           NetworkDelegate* network_delegate) const;

  // Allows interceptors to hijack the request after examining the new location
  // of a redirect. Returns NULL if no interceptor intervenes.
  URLRequestJob* MaybeInterceptRedirect(URLRequest* request,
                                        NetworkDelegate* network_delegate,
                                        const GURL& location) const;

  // Allows interceptors to hijack the request after examining the response
  // status and headers. This is also called when there is no server response
  // at all to allow interception of failed requests due to network errors.
  // Returns NULL if no interceptor intervenes.
  URLRequestJob* MaybeInterceptResponse(
      URLRequest* request, NetworkDelegate* network_delegate) const;

  // Returns true if there is a protocol factory registered for the given
  // scheme.  Note: also returns true if there is a built-in handler for the
  // given scheme.
  bool SupportsScheme(const std::string& scheme) const;

  // Register a protocol factory associated with the given scheme.  The factory
  // parameter may be null to clear any existing association.  Returns the
  // previously registered protocol factory if any.
  URLRequest::ProtocolFactory* RegisterProtocolFactory(
      const std::string& scheme, URLRequest::ProtocolFactory* factory);

  // Register/unregister a request interceptor.
  void RegisterRequestInterceptor(URLRequest::Interceptor* interceptor);
  void UnregisterRequestInterceptor(URLRequest::Interceptor* interceptor);

 private:
  typedef std::map<std::string, URLRequest::ProtocolFactory*> FactoryMap;
  typedef std::vector<URLRequest::Interceptor*> InterceptorList;
  friend struct DefaultSingletonTraits<URLRequestJobManager>;

  URLRequestJobManager();
  ~URLRequestJobManager();

  // The first guy to call this function sets the allowed thread.  This way we
  // avoid needing to define that thread externally.  Since we expect all
  // callers to be on the same thread, we don't worry about threads racing to
  // set the allowed thread.
  bool IsAllowedThread() const {
#if 0
    if (!allowed_thread_initialized_) {
      allowed_thread_ = base::PlatformThread::CurrentId();
      allowed_thread_initialized_ = true;
    }
    return allowed_thread_ == base::PlatformThread::CurrentId();
#else
    // The previous version of this check used GetCurrentThread on Windows to
    // get thread handles to compare. Unfortunately, GetCurrentThread returns
    // a constant pseudo-handle (0xFFFFFFFE), and therefore IsAllowedThread
    // always returned true. The above code that's turned off is the correct
    // code, but causes the tree to turn red because some caller isn't
    // respecting our thread requirements. We're turning off the check for now;
    // bug http://b/issue?id=1338969 has been filed to fix things and turn the
    // check back on.
    return true;
  }

  // We use this to assert that CreateJob and the registration functions all
  // run on the same thread.
  mutable base::PlatformThreadId allowed_thread_;
  mutable bool allowed_thread_initialized_;
#endif

  mutable base::Lock lock_;
  FactoryMap factories_;
  InterceptorList interceptors_;

  DISALLOW_COPY_AND_ASSIGN(URLRequestJobManager);
};

}  // namespace net

#endif  // NET_URL_REQUEST_URL_REQUEST_JOB_MANAGER_H_
