// Copyright (c) 2015 Marshall A. Greenblatt. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//    * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//    * Neither the name of Google Inc. nor the name Chromium Embedded
// Framework nor the names of its contributors may be used to endorse
// or promote products derived from this software without specific prior
// written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---------------------------------------------------------------------------
//
// The contents of this file are only available to applications that link
// against the libcef_dll_wrapper target.
//

#ifndef CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_
#define CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_
#pragma once

#include <list>

#include "include/base/cef_macros.h"
#include "include/base/cef_ref_counted.h"
#include "include/base/cef_scoped_ptr.h"
#include "include/base/cef_weak_ptr.h"
#include "include/cef_request_handler.h"
#include "include/wrapper/cef_closure_task.h"
#include "include/wrapper/cef_helpers.h"

///
// Class for managing multiple resource providers. For each resource request
// providers will be called in order and have the option to (a) handle the
// request by returning a CefResourceHandler, (b) pass the request to the next
// provider in order, or (c) stop handling the request. See comments on the
// Request object for additional usage information. The methods of this class
// may be called on any browser process thread unless otherwise indicated.
///
class CefResourceManager
    : public base::RefCountedThreadSafe<CefResourceManager,
                                        CefDeleteOnIOThread> {
 public:
  ///
  // Provides an opportunity to modify |url| before it is passed to a provider.
  // For example, the implementation could rewrite |url| to include a default
  // file extension. |url| will be fully qualified and may contain query or
  // fragment components.
  ///
  typedef base::Callback<std::string(const std::string& /*url*/)> UrlFilter;

  ///
  // Used to resolve mime types for URLs, usually based on the file extension.
  // |url| will be fully qualified and may contain query or fragment components.
  ///
  typedef base::Callback<std::string(const std::string& /*url*/)>
      MimeTypeResolver;

 private:
  // Values that stay with a request as it moves between providers.
  struct RequestParams {
    std::string url_;
    CefRefPtr<CefBrowser> browser_;
    CefRefPtr<CefFrame> frame_;
    CefRefPtr<CefRequest> request_;
    UrlFilter url_filter_;
    MimeTypeResolver mime_type_resolver_;
  };

  // Values that are associated with the pending request only.
  struct RequestState;

 public:
  ///
  // Object representing a request. Each request object is used for a single
  // call to Provider::OnRequest and will become detached (meaning the callbacks
  // will no longer trigger) after Request::Continue or Request::Stop is called.
  // A request passed to Provider::OnRequestCanceled will already have been
  // detached. The methods of this class may be called on any browser process
  // thread.
  ///
  class Request : public base::RefCountedThreadSafe<Request> {
   public:
    ///
    // Returns the URL associated with this request. The returned value will be
    // fully qualified but will not contain query or fragment components. It
    // will already have been passed through the URL filter.
    ///
    std::string url() const { return params_.url_; }

    ///
    // Returns the CefBrowser associated with this request.
    ///
    CefRefPtr<CefBrowser> browser() const { return params_.browser_; }

    ///
    // Returns the CefFrame associated with this request.
    ///
    CefRefPtr<CefFrame> frame() const { return params_.frame_; }

    ///
    // Returns the CefRequest associated with this request.
    ///
    CefRefPtr<CefRequest> request() const { return params_.request_; }

    ///
    // Returns the current URL filter.
    ///
    const CefResourceManager::UrlFilter& url_filter() const {
      return params_.url_filter_;
    }

    ///
    // Returns the current mime type resolver.
    ///
    const CefResourceManager::MimeTypeResolver& mime_type_resolver() const {
      return params_.mime_type_resolver_;
    }

    ///
    // Continue handling the request. If |handler| is non-NULL then no
    // additional providers will be called and the |handler| value will be
    // returned via CefResourceManager::GetResourceHandler. If |handler| is NULL
    // then the next provider in order, if any, will be called. If there are no
    // additional providers then NULL will be returned via CefResourceManager::
    // GetResourceHandler.
    ///
    void Continue(CefRefPtr<CefResourceHandler> handler);

    ///
    // Stop handling the request. No additional providers will be called and
    // NULL will be returned via CefResourceManager::GetResourceHandler.
    ///
    void Stop();

   private:
    // Only allow deletion via scoped_refptr.
    friend class base::RefCountedThreadSafe<Request>;

    friend class CefResourceManager;

    // The below methods are called on the browser process IO thread.

    explicit Request(scoped_ptr<RequestState> state);

    scoped_ptr<RequestState> SendRequest();
    bool HasState();

    static void ContinueOnIOThread(scoped_ptr<RequestState> state,
                                   CefRefPtr<CefResourceHandler> handler);
    static void StopOnIOThread(scoped_ptr<RequestState> state);

    // Will be non-NULL while the request is pending. Only accessed on the
    // browser process IO thread.
    scoped_ptr<RequestState> state_;

    // Params that stay with this request object. Safe to access on any thread.
    RequestParams params_;

    DISALLOW_COPY_AND_ASSIGN(Request);
  };

  typedef std::list<scoped_refptr<Request>> RequestList;

  ///
  // Interface implemented by resource providers. A provider may be created on
  // any thread but the methods will be called on, and the object will be
  // destroyed on, the browser process IO thread.
  ///
  class Provider {
   public:
    ///
    // Called to handle a request. If the provider knows immediately that it
    // will not handle the request return false. Otherwise, return true and call
    // Request::Continue or Request::Stop either in this method or
    // asynchronously to indicate completion. See comments on Request for
    // additional usage information.
    ///
    virtual bool OnRequest(scoped_refptr<Request> request) = 0;

    ///
    // Called when a request has been canceled. It is still safe to dereference
    // |request| but any calls to Request::Continue or Request::Stop will be
    // ignored.
    ///
    virtual void OnRequestCanceled(scoped_refptr<Request> request) {}

    virtual ~Provider() {}
  };

  CefResourceManager();

  ///
  // Add a provider that maps requests for |url| to |content|. |url| should be
  // fully qualified but not include a query or fragment component. If
  // |mime_type| is empty the MimeTypeResolver will be used. See comments on
  // AddProvider for usage of the |order| and |identifier| parameters.
  ///
  void AddContentProvider(const std::string& url,
                          const std::string& content,
                          const std::string& mime_type,
                          int order,
                          const std::string& identifier);

  ///
  // Add a provider that maps requests that start with |url_path| to files under
  // |directory_path|. |url_path| should include an origin and optional path
  // component only. Files will be loaded when a matching URL is requested.
  // See comments on AddProvider for usage of the |order| and |identifier|
  // parameters.
  ///
  void AddDirectoryProvider(const std::string& url_path,
                            const std::string& directory_path,
                            int order,
                            const std::string& identifier);

  ///
  // Add a provider that maps requests that start with |url_path| to files
  // stored in the archive file at |archive_path|. |url_path| should include an
  // origin and optional path component only. The archive file will be loaded
  // when a matching URL is requested for the first time. See comments on
  // AddProvider for usage of the |order| and |identifier| parameters.
  ///
  void AddArchiveProvider(const std::string& url_path,
                          const std::string& archive_path,
                          const std::string& password,
                          int order,
                          const std::string& identifier);

  ///
  // Add a provider. This object takes ownership of |provider|. Providers will
  // be called in ascending order based on the |order| value. Multiple providers
  // sharing the same |order| value will be called in the order that they were
  // added. The |identifier| value, which does not need to be unique, can be
  // used to remove the provider at a later time.
  ///
  void AddProvider(Provider* provider,
                   int order,
                   const std::string& identifier);

  ///
  // Remove all providers with the specified |identifier| value. If any removed
  // providers have pending requests the Provider::OnRequestCancel method will
  // be called. The removed providers may be deleted immediately or at a later
  // time.
  ///
  void RemoveProviders(const std::string& identifier);

  ///
  // Remove all providers. If any removed providers have pending requests the
  // Provider::OnRequestCancel method will be called. The removed providers may
  // be deleted immediately or at a later time.
  ///
  void RemoveAllProviders();

  ///
  // Set the url filter. If not set the default no-op filter will be used.
  // Changes to this value will not affect currently pending requests.
  ///
  void SetUrlFilter(const UrlFilter& filter);

  ///
  // Set the mime type resolver. If not set the default resolver will be used.
  // Changes to this value will not affect currently pending requests.
  ///
  void SetMimeTypeResolver(const MimeTypeResolver& resolver);

  // The below methods should be called from other CEF handlers. They must be
  // called exactly as documented for the manager to function correctly.

  ///
  // Called from CefRequestHandler::OnBeforeResourceLoad on the browser process
  // IO thread.
  ///
  cef_return_value_t OnBeforeResourceLoad(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request,
      CefRefPtr<CefRequestCallback> callback);

  ///
  // Called from CefRequestHandler::GetResourceHandler on the browser process
  // IO thread.
  ///
  CefRefPtr<CefResourceHandler> GetResourceHandler(
      CefRefPtr<CefBrowser> browser,
      CefRefPtr<CefFrame> frame,
      CefRefPtr<CefRequest> request);

 private:
  // Only allow deletion via scoped_refptr.
  friend struct CefDeleteOnThread<TID_IO>;
  friend class base::RefCountedThreadSafe<CefResourceManager,
                                          CefDeleteOnIOThread>;

  ~CefResourceManager();

  // Provider and associated information.
  struct ProviderEntry;
  typedef std::list<ProviderEntry*> ProviderEntryList;

  // Values associated with the pending request only. Ownership will be passed
  // between requests and the resource manager as request handling proceeds.
  struct RequestState {
    ~RequestState();

    base::WeakPtr<CefResourceManager> manager_;

    // Callback to execute once request handling is complete.
    CefRefPtr<CefRequestCallback> callback_;

    // Position of the currently associated ProviderEntry in the |providers_|
    // list.
    ProviderEntryList::iterator current_entry_pos_;

    // Position of this request object in the currently associated
    // ProviderEntry's |pending_requests_| list.
    RequestList::iterator current_request_pos_;

    // Params that will be copied to each request object.
    RequestParams params_;
  };

  // Methods that manage request state between requests. Called on the browser
  // process IO thread.
  bool SendRequest(scoped_ptr<RequestState> state);
  void ContinueRequest(scoped_ptr<RequestState> state,
                       CefRefPtr<CefResourceHandler> handler);
  void StopRequest(scoped_ptr<RequestState> state);
  bool IncrementProvider(RequestState* state);
  void DetachRequestFromProvider(RequestState* state);
  void GetNextValidProvider(ProviderEntryList::iterator& iterator);
  void DeleteProvider(ProviderEntryList::iterator& iterator, bool stop);

  // The below members are only accessed on the browser process IO thread.

  // List of providers including additional associated information.
  ProviderEntryList providers_;

  // Map of response ID to pending CefResourceHandler object.
  typedef std::map<uint64, CefRefPtr<CefResourceHandler>> PendingHandlersMap;
  PendingHandlersMap pending_handlers_;

  UrlFilter url_filter_;
  MimeTypeResolver mime_type_resolver_;

  // Must be the last member. Created and accessed on the IO thread.
  scoped_ptr<base::WeakPtrFactory<CefResourceManager>> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(CefResourceManager);
};

#endif  // CEF_INCLUDE_WRAPPER_CEF_RESOURCE_MANAGER_H_
