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

#include "extensions/renderer/api_activity_logger.h"

#include <stddef.h>

#include <string>

#include "base/bind.h"
#include "content/public/renderer/render_thread.h"
#include "content/public/renderer/v8_value_converter.h"
#include "extensions/common/extension_messages.h"
#include "extensions/renderer/activity_log_converter_strategy.h"
#include "extensions/renderer/dispatcher.h"
#include "extensions/renderer/extensions_renderer_client.h"
#include "extensions/renderer/script_context.h"

namespace extensions {

namespace {
bool g_log_for_testing = false;
}

APIActivityLogger::APIActivityLogger(ScriptContext* context)
    : ObjectBackedNativeHandler(context) {}

APIActivityLogger::~APIActivityLogger() {}

void APIActivityLogger::AddRoutes() {
  RouteHandlerFunction("LogEvent",
                       base::BindRepeating(&APIActivityLogger::LogForJS,
                                           base::Unretained(this), EVENT));
  RouteHandlerFunction("LogAPICall",
                       base::BindRepeating(&APIActivityLogger::LogForJS,
                                           base::Unretained(this), APICALL));
}

// static
bool APIActivityLogger::IsLoggingEnabled() {
  const Dispatcher* dispatcher =
      ExtensionsRendererClient::Get()->GetDispatcher();
  return (dispatcher &&  // dispatcher can be null in unittests.
          dispatcher->activity_logging_enabled()) ||
         g_log_for_testing;
}

// static
void APIActivityLogger::LogAPICall(
    v8::Local<v8::Context> context,
    const std::string& call_name,
    const std::vector<v8::Local<v8::Value>>& arguments) {
  if (!IsLoggingEnabled())
    return;

  ScriptContext* script_context =
      ScriptContextSet::GetContextByV8Context(context);
  auto value_args = std::make_unique<base::ListValue>();
  std::unique_ptr<content::V8ValueConverter> converter =
      content::V8ValueConverter::Create();
  ActivityLogConverterStrategy strategy;
  converter->SetFunctionAllowed(true);
  converter->SetStrategy(&strategy);
  value_args->Reserve(arguments.size());
  // TODO(devlin): This doesn't protect against custom properties, so it might
  // not perfectly reflect the passed arguments.
  for (const auto& arg : arguments) {
    std::unique_ptr<base::Value> converted_arg =
        converter->FromV8Value(arg, context);
    value_args->Append(converted_arg ? std::move(converted_arg)
                                     : std::make_unique<base::Value>());
  }

  LogInternal(APICALL, script_context->GetExtensionID(), call_name,
              std::move(value_args), std::string());
}

void APIActivityLogger::LogEvent(ScriptContext* script_context,
                                 const std::string& event_name,
                                 std::unique_ptr<base::ListValue> arguments) {
  if (!IsLoggingEnabled())
    return;

  LogInternal(EVENT, script_context->GetExtensionID(), event_name,
              std::move(arguments), std::string());
}

void APIActivityLogger::set_log_for_testing(bool log) {
  g_log_for_testing = log;
}

void APIActivityLogger::LogForJS(
    const CallType call_type,
    const v8::FunctionCallbackInfo<v8::Value>& args) {
  CHECK_GT(args.Length(), 2);
  CHECK(args[0]->IsString());
  CHECK(args[1]->IsString());
  CHECK(args[2]->IsArray());

  if (!IsLoggingEnabled())
    return;

  v8::Isolate* isolate = args.GetIsolate();
  v8::HandleScope handle_scope(isolate);
  v8::Local<v8::Context> context = isolate->GetCurrentContext();

  std::string extension_id = *v8::String::Utf8Value(isolate, args[0]);
  std::string call_name = *v8::String::Utf8Value(isolate, args[1]);
  std::string extra;
  if (args.Length() == 4) {  // Extras are optional.
    CHECK(args[3]->IsString());
    extra = *v8::String::Utf8Value(isolate, args[3]);
  }

  // Get the array of call arguments.
  auto arguments = std::make_unique<base::ListValue>();
  v8::Local<v8::Array> arg_array = v8::Local<v8::Array>::Cast(args[2]);
  if (arg_array->Length() > 0) {
    arguments->Reserve(arg_array->Length());
    std::unique_ptr<content::V8ValueConverter> converter =
        content::V8ValueConverter::Create();
    ActivityLogConverterStrategy strategy;
    converter->SetFunctionAllowed(true);
    converter->SetStrategy(&strategy);
    for (size_t i = 0; i < arg_array->Length(); ++i) {
      // TODO(crbug.com/913942): Possibly replace ToLocalChecked here with
      // actual error handling.
      std::unique_ptr<base::Value> converted_arg = converter->FromV8Value(
          arg_array->Get(context, i).ToLocalChecked(), context);
      arguments->Append(converted_arg ? std::move(converted_arg)
                                      : std::make_unique<base::Value>());
    }
  }

  LogInternal(call_type, extension_id, call_name, std::move(arguments), extra);
}

// static
void APIActivityLogger::LogInternal(const CallType call_type,
                                    const std::string& extension_id,
                                    const std::string& call_name,
                                    std::unique_ptr<base::ListValue> arguments,
                                    const std::string& extra) {
  DCHECK(IsLoggingEnabled());
  ExtensionHostMsg_APIActionOrEvent_Params params;
  params.api_call = call_name;
  params.arguments.Swap(arguments.get());
  params.extra = extra;
  if (call_type == APICALL) {
    content::RenderThread::Get()->Send(
        new ExtensionHostMsg_AddAPIActionToActivityLog(extension_id, params));
  } else if (call_type == EVENT) {
    content::RenderThread::Get()->Send(
        new ExtensionHostMsg_AddEventToActivityLog(extension_id, params));
  }
}

}  // namespace extensions
