// Copyright 2015 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.

#include "extensions/renderer/wake_event_page.h"

#include <memory>
#include <utility>

#include "base/atomic_sequence_num.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/stl_util.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/worker_thread.h"
#include "extensions/common/extension_messages.h"
#include "extensions/renderer/object_backed_native_handler.h"
#include "extensions/renderer/script_context.h"
#include "extensions/renderer/v8_helpers.h"
#include "ipc/ipc_message.h"
#include "ipc/ipc_message_macros.h"

namespace extensions {

using namespace v8_helpers;

namespace {

base::LazyInstance<WakeEventPage>::DestructorAtExit g_wake_event_page_instance =
    LAZY_INSTANCE_INITIALIZER;

constexpr char kWakeEventPageFunctionName[] = "WakeEventPage";

}  // namespace

class WakeEventPage::WakeEventPageNativeHandler
    : public ObjectBackedNativeHandler {
 public:
  // Handles own lifetime.
  WakeEventPageNativeHandler(ScriptContext* context,
                             const MakeRequestCallback& make_request)
      : ObjectBackedNativeHandler(context),
        make_request_(make_request),
        weak_ptr_factory_(this) {
    // Delete self on invalidation. base::Unretained because by definition this
    // can't be deleted before it's deleted.
    context->AddInvalidationObserver(base::BindOnce(
        &WakeEventPageNativeHandler::DeleteSelf, base::Unretained(this)));
  }

  // ObjectBackedNativeHandler:
  void AddRoutes() override {
    // Use Unretained not a WeakPtr because RouteHandlerFunction is tied to the
    // lifetime of this, so there is no way for DoWakeEventPage to be called
    // after destruction.
    RouteHandlerFunction(
        kWakeEventPageFunctionName,
        base::BindRepeating(&WakeEventPageNativeHandler::DoWakeEventPage,
                            base::Unretained(this)));
  }

  ~WakeEventPageNativeHandler() override {}

 private:
  void DeleteSelf() {
    Invalidate();
    delete this;
  }

  // Called by JavaScript with a single argument, the function to call when the
  // event page has been woken.
  void DoWakeEventPage(const v8::FunctionCallbackInfo<v8::Value>& args) {
    CHECK_EQ(1, args.Length());
    CHECK(args[0]->IsFunction());
    v8::Global<v8::Function> callback(args.GetIsolate(),
                                      args[0].As<v8::Function>());

    const std::string& extension_id = context()->GetExtensionID();
    CHECK(!extension_id.empty());

    make_request_.Run(
        extension_id,
        base::Bind(&WakeEventPageNativeHandler::OnEventPageIsAwake,
                   weak_ptr_factory_.GetWeakPtr(), base::Passed(&callback)));
  }

  void OnEventPageIsAwake(v8::Global<v8::Function> callback, bool success) {
    v8::Isolate* isolate = context()->isolate();
    v8::HandleScope handle_scope(isolate);
    v8::Local<v8::Value> args[] = {
        v8::Boolean::New(isolate, success),
    };
    context()->SafeCallFunction(v8::Local<v8::Function>::New(isolate, callback),
                                base::size(args), args);
  }

  MakeRequestCallback make_request_;
  base::WeakPtrFactory<WakeEventPageNativeHandler> weak_ptr_factory_;

  DISALLOW_COPY_AND_ASSIGN(WakeEventPageNativeHandler);
};

// static
WakeEventPage* WakeEventPage::Get() {
  return g_wake_event_page_instance.Pointer();
}

void WakeEventPage::Init(content::RenderThread* render_thread) {
  DCHECK(render_thread);
  DCHECK_EQ(content::RenderThread::Get(), render_thread);
  DCHECK(!message_filter_);

  message_filter_ = render_thread->GetSyncMessageFilter();
  render_thread->AddObserver(this);
}

v8::Local<v8::Function> WakeEventPage::GetForContext(ScriptContext* context) {
  DCHECK(message_filter_);

  v8::Isolate* isolate = context->isolate();
  v8::EscapableHandleScope handle_scope(isolate);
  v8::Local<v8::Context> v8_context = context->v8_context();
  v8::Context::Scope context_scope(v8_context);

  // Cache the imported function as a hidden property on the global object of
  // |v8_context|. Creating it isn't free.
  v8::Local<v8::Private> kWakeEventPageKey =
      v8::Private::ForApi(isolate, ToV8StringUnsafe(isolate, "WakeEventPage"));
  v8::Local<v8::Value> wake_event_page;
  if (!v8_context->Global()
           ->GetPrivate(v8_context, kWakeEventPageKey)
           .ToLocal(&wake_event_page) ||
      wake_event_page->IsUndefined()) {
    // Implement this using a NativeHandler, which requires a function name
    // (arbitrary in this case). Handles own lifetime.
    WakeEventPageNativeHandler* native_handler = new WakeEventPageNativeHandler(
        context, base::Bind(&WakeEventPage::MakeRequest,
                            // Safe, owned by a LazyInstance.
                            base::Unretained(this)));
    native_handler->Initialize();

    // Extract and cache the wake-event-page function from the native handler.
    wake_event_page = GetPropertyUnsafe(
        v8_context, native_handler->NewInstance(), kWakeEventPageFunctionName);
    v8_context->Global()
        ->SetPrivate(v8_context, kWakeEventPageKey, wake_event_page)
        .FromJust();
  }

  CHECK(wake_event_page->IsFunction());
  return handle_scope.Escape(wake_event_page.As<v8::Function>());
}

WakeEventPage::RequestData::RequestData(int thread_id,
                                        const OnResponseCallback& on_response)
    : thread_id(thread_id), on_response(on_response) {}

WakeEventPage::RequestData::~RequestData() {}

WakeEventPage::WakeEventPage() {}

WakeEventPage::~WakeEventPage() {}

void WakeEventPage::MakeRequest(const std::string& extension_id,
                                const OnResponseCallback& on_response) {
  static base::AtomicSequenceNumber sequence_number;
  int request_id = sequence_number.GetNext();
  {
    base::AutoLock lock(requests_lock_);
    requests_[request_id] = std::make_unique<RequestData>(
        content::WorkerThread::GetCurrentId(), on_response);
  }
  message_filter_->Send(
      new ExtensionHostMsg_WakeEventPage(request_id, extension_id));
}

bool WakeEventPage::OnControlMessageReceived(const IPC::Message& message) {
  bool handled = true;
  IPC_BEGIN_MESSAGE_MAP(WakeEventPage, message)
    IPC_MESSAGE_HANDLER(ExtensionMsg_WakeEventPageResponse,
                        OnWakeEventPageResponse)
    IPC_MESSAGE_UNHANDLED(handled = false)
  IPC_END_MESSAGE_MAP()
  return handled;
}

void WakeEventPage::OnWakeEventPageResponse(int request_id, bool success) {
  std::unique_ptr<RequestData> request_data;
  {
    base::AutoLock lock(requests_lock_);
    auto it = requests_.find(request_id);
    CHECK(it != requests_.end()) << "No request with ID " << request_id;
    request_data = std::move(it->second);
    requests_.erase(it);
  }
  if (request_data->thread_id == 0) {
    // Thread ID of 0 means it wasn't called on a worker thread, so safe to
    // call immediately.
    request_data->on_response.Run(success);
  } else {
    content::WorkerThread::PostTask(
        request_data->thread_id,
        base::Bind(request_data->on_response, success));
  }
}

}  //  namespace extensions
