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

#include <string>

#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h"
#include "content/common/content_export.h"
#include "content/public/browser/global_request_id.h"
#include "url/gurl.h"
#include "webkit/common/resource_type.h"

namespace net {
class SSLInfo;
class URLRequest;
}  // namespace net

namespace content {

class ResourceDispatcherHostImpl;
class SSLCertErrorHandler;
class SSLManager;

// An SSLErrorHandler carries information from the IO thread to the UI thread
// and is dispatched to the appropriate SSLManager when it arrives on the
// UI thread.  Subclasses should override the OnDispatched/OnDispatchFailed
// methods to implement the actions that should be taken on the UI thread.
// These methods can call the different convenience methods ContinueRequest/
// CancelRequest to perform any required action on the net::URLRequest the
// ErrorHandler was created with.
//
// IMPORTANT NOTE:
//
//   If you are not doing anything in OnDispatched/OnDispatchFailed, make sure
//   you call TakeNoAction().  This is necessary for ensuring the instance is
//   not leaked.
//
class SSLErrorHandler : public base::RefCountedThreadSafe<SSLErrorHandler> {
 public:
  // Delegate functions must be called from IO thread. All functions accept
  // |id| as the first argument. |id| is a copy of the second argument of
  // SSLManager::OnSSLCertificateError() and represents the request.
  // Finally, CancelSSLRequest() or ContinueSSLRequest() will be called after
  // SSLErrorHandler makes a decision on the SSL error.
  class CONTENT_EXPORT Delegate {
   public:
    // Called when SSLErrorHandler decides to cancel the request because of
    // the SSL error.
    virtual void CancelSSLRequest(const GlobalRequestID& id,
                                  int error,
                                  const net::SSLInfo* ssl_info) = 0;

    // Called when SSLErrorHandler decides to continue the request despite the
    // SSL error.
    virtual void ContinueSSLRequest(const GlobalRequestID& id) = 0;

   protected:
    virtual ~Delegate() {}
  };

  virtual SSLCertErrorHandler* AsSSLCertErrorHandler();

  // Find the appropriate SSLManager for the net::URLRequest and begin handling
  // this error.
  //
  // Call on UI thread.
  void Dispatch();

  // Available on either thread.
  const GURL& request_url() const { return request_url_; }

  // Available on either thread.
  ResourceType::Type resource_type() const { return resource_type_; }

  // Cancels the associated net::URLRequest.
  // This method can be called from OnDispatchFailed and OnDispatched.
  CONTENT_EXPORT void CancelRequest();

  // Continue the net::URLRequest ignoring any previous errors.  Note that some
  // errors cannot be ignored, in which case this will result in the request
  // being canceled.
  // This method can be called from OnDispatchFailed and OnDispatched.
  void ContinueRequest();

  // Cancels the associated net::URLRequest and mark it as denied.  The renderer
  // processes such request in a special manner, optionally replacing them
  // with alternate content (typically frames content is replaced with a
  // warning message).
  // This method can be called from OnDispatchFailed and OnDispatched.
  void DenyRequest();

  // Does nothing on the net::URLRequest but ensures the current instance ref
  // count is decremented appropriately.  Subclasses that do not want to
  // take any specific actions in their OnDispatched/OnDispatchFailed should
  // call this.
  void TakeNoAction();

  int render_process_id() const { return render_process_id_; }
  int render_frame_id() const { return render_frame_id_; }

 protected:
  friend class base::RefCountedThreadSafe<SSLErrorHandler>;

  // Construct on the IO thread.
  SSLErrorHandler(const base::WeakPtr<Delegate>& delegate,
                  const GlobalRequestID& id,
                  ResourceType::Type resource_type,
                  const GURL& url,
                  int render_process_id,
                  int render_frame_id);

  virtual ~SSLErrorHandler();

  // The following 2 methods are the methods subclasses should implement.
  virtual void OnDispatchFailed();

  // Can use the manager_ member.
  virtual void OnDispatched();

  // Should only be accessed on the UI thread.
  SSLManager* manager_;  // Our manager.

  // The id of the request associated with this object.
  // Should only be accessed from the IO thread.
  GlobalRequestID request_id_;

  // The delegate we are associated with.
  base::WeakPtr<Delegate> delegate_;

 private:
  // Completes the CancelRequest operation on the IO thread.
  // Call on the IO thread.
  void CompleteCancelRequest(int error);

  // Completes the ContinueRequest operation on the IO thread.
  //
  // Call on the IO thread.
  void CompleteContinueRequest();

  // Derefs this instance.
  // Call on the IO thread.
  void CompleteTakeNoAction();

  // We use these members to find the correct SSLManager when we arrive on
  // the UI thread.
  int render_process_id_;
  int render_frame_id_;

  // The URL that we requested.
  // This read-only member can be accessed on any thread.
  const GURL request_url_;

  // What kind of resource is associated with the requested that generated
  // that error.
  // This read-only member can be accessed on any thread.
  const ResourceType::Type resource_type_;

  // A flag to make sure we notify the net::URLRequest exactly once.
  // Should only be accessed on the IO thread
  bool request_has_been_notified_;

  DISALLOW_COPY_AND_ASSIGN(SSLErrorHandler);
};

}  // namespace content

#endif  // CONTENT_BROWSER_SSL_SSL_ERROR_HANDLER_H_
