/*
 * Copyright (C) 2013 Google Inc. 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 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.
 */

#ifndef WebEmbeddedWorkerImpl_h
#define WebEmbeddedWorkerImpl_h

#include "core/workers/WorkerLoaderProxy.h"

#include <memory>
#include "platform/heap/Handle.h"
#include "public/platform/WebContentSecurityPolicy.h"
#include "public/web/WebDevToolsAgentClient.h"
#include "public/web/WebEmbeddedWorker.h"
#include "public/web/WebEmbeddedWorkerStartData.h"
#include "public/web/WebFrameClient.h"

namespace blink {

class ThreadableLoadingContext;
class ParentFrameTaskRunners;
class ServiceWorkerGlobalScopeProxy;
class WebLocalFrameImpl;
class WebView;
class WorkerInspectorProxy;
class WorkerScriptLoader;
class WorkerThread;

class WebEmbeddedWorkerImpl final : public WebEmbeddedWorker,
                                    public WebFrameClient,
                                    public WebDevToolsAgentClient,
                                    private WorkerLoaderProxyProvider {
  WTF_MAKE_NONCOPYABLE(WebEmbeddedWorkerImpl);

 public:
  WebEmbeddedWorkerImpl(std::unique_ptr<WebServiceWorkerContextClient>,
                        std::unique_ptr<WebWorkerContentSettingsClientProxy>);
  ~WebEmbeddedWorkerImpl() override;

  // WebEmbeddedWorker overrides.
  void StartWorkerContext(const WebEmbeddedWorkerStartData&) override;
  void TerminateWorkerContext() override;
  void ResumeAfterDownload() override;
  void AttachDevTools(const WebString& host_id, int session_id) override;
  void ReattachDevTools(const WebString& host_id,
                        int session_id,
                        const WebString& saved_state) override;
  void DetachDevTools() override;
  void DispatchDevToolsMessage(int session_id,
                               int call_id,
                               const WebString& method,
                               const WebString& message) override;
  void AddMessageToConsole(const WebConsoleMessage&) override;

  void PostMessageToPageInspector(const WTF::String&);

 private:
  void PrepareShadowPageForLoader();
  void LoadShadowPage();

  // WebFrameClient overrides.
  void DidFinishDocumentLoad(WebLocalFrame*) override;

  // WebDevToolsAgentClient overrides.
  void SendProtocolMessage(int session_id,
                           int call_id,
                           const WebString&,
                           const WebString&) override;
  void ResumeStartup() override;
  WebDevToolsAgentClient::WebKitClientMessageLoop* CreateClientMessageLoop()
      override;

  void OnScriptLoaderFinished();
  void StartWorkerThread();

  // WorkerLoaderProxyProvider
  void PostTaskToLoader(const WebTraceLocation&,
                        std::unique_ptr<WTF::CrossThreadClosure>) override;
  void PostTaskToWorkerGlobalScope(
      const WebTraceLocation&,
      std::unique_ptr<WTF::CrossThreadClosure>) override;
  ThreadableLoadingContext* GetThreadableLoadingContext() override;

  WebEmbeddedWorkerStartData worker_start_data_;

  std::unique_ptr<WebServiceWorkerContextClient> worker_context_client_;

  // This is kept until startWorkerContext is called, and then passed on
  // to WorkerContext.
  std::unique_ptr<WebWorkerContentSettingsClientProxy> content_settings_client_;

  // Kept around only while main script loading is ongoing.
  RefPtr<WorkerScriptLoader> main_script_loader_;

  // Owned by the main thread, but will be accessed by the worker when
  // posting tasks.
  CrossThreadPersistent<ParentFrameTaskRunners> main_thread_task_runners_;

  std::unique_ptr<WorkerThread> worker_thread_;
  RefPtr<WorkerLoaderProxy> loader_proxy_;
  Persistent<ServiceWorkerGlobalScopeProxy> worker_global_scope_proxy_;
  Persistent<WorkerInspectorProxy> worker_inspector_proxy_;

  // 'shadow page' - created to proxy loading requests from the worker.
  // Both WebView and WebFrame objects are close()'ed (where they're
  // deref'ed) when this EmbeddedWorkerImpl is destructed, therefore they
  // are guaranteed to exist while this object is around.
  WebView* web_view_;

  Persistent<WebLocalFrameImpl> main_frame_;
  Persistent<ThreadableLoadingContext> loading_context_;

  bool loading_shadow_page_;
  bool asked_to_terminate_;

  enum WaitingForDebuggerState { kWaitingForDebugger, kNotWaitingForDebugger };

  enum {
    kDontPauseAfterDownload,
    kDoPauseAfterDownload,
    kIsPausedAfterDownload
  } pause_after_download_state_;

  WaitingForDebuggerState waiting_for_debugger_state_;
};

}  // namespace blink

#endif  // WebEmbeddedWorkerImpl_h
