// Copyright (c) 2014 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_CHILD_RESOURCE_SCHEDULING_FILTER_H_
#define CONTENT_CHILD_RESOURCE_SCHEDULING_FILTER_H_

#include <stdint.h>

#include <map>

#include "base/containers/hash_tables.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "base/single_thread_task_runner.h"
#include "content/common/content_export.h"
#include "ipc/message_filter.h"

namespace blink {
class WebTaskRunner;
}

namespace content {
class ResourceDispatcher;

// This filter is used to dispatch resource messages on a specific
// SingleThreadTaskRunner to facilitate task scheduling.
class CONTENT_EXPORT ResourceSchedulingFilter : public IPC::MessageFilter {
 public:
  ResourceSchedulingFilter(const scoped_refptr<base::SingleThreadTaskRunner>&
                               main_thread_task_runner,
                           ResourceDispatcher* resource_dispatcher);

  // IPC::MessageFilter overrides:
  bool OnMessageReceived(const IPC::Message& message) override;

  bool GetSupportedMessageClasses(
      std::vector<uint32_t>* supported_message_classes) const override;

  // Sets the task runner associated with request messages with |id|.
  void SetRequestIdTaskRunner(
      int id, scoped_ptr<blink::WebTaskRunner> web_task_runner);

  // Removes the task runner associated with |id|.
  void ClearRequestIdTaskRunner(int id);

  void DispatchMessage(const IPC::Message& message);

 private:
  ~ResourceSchedulingFilter() override;

  using RequestIdToTaskRunnerMap =
      std::map<int, scoped_ptr<blink::WebTaskRunner>>;

  // This lock guards |request_id_to_task_runner_map_|
  base::Lock request_id_to_task_runner_map_lock_;
  RequestIdToTaskRunnerMap request_id_to_task_runner_map_;

  scoped_refptr<base::SingleThreadTaskRunner> main_thread_task_runner_;
  ResourceDispatcher* resource_dispatcher_;  // NOT OWNED
  base::WeakPtrFactory<ResourceSchedulingFilter> weak_ptr_factory_;

 private:
  DISALLOW_COPY_AND_ASSIGN(ResourceSchedulingFilter);
};

}  // namespace content

#endif  // CONTENT_CHILD_RESOURCE_SCHEDULING_FILTER_H_