// Copyright 2017 the V8 project 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 "src/builtins/builtins-utils.h"
#include "src/builtins/builtins.h"

#include "src/api.h"
#include "src/debug/interface-types.h"
#include "src/objects-inl.h"

namespace v8 {
namespace internal {

// -----------------------------------------------------------------------------
// Console

#define CONSOLE_METHOD_LIST(V)      \
  V(Debug, debug)                   \
  V(Error, error)                   \
  V(Info, info)                     \
  V(Log, log)                       \
  V(Warn, warn)                     \
  V(Dir, dir)                       \
  V(DirXml, dirXml)                 \
  V(Table, table)                   \
  V(Trace, trace)                   \
  V(Group, group)                   \
  V(GroupCollapsed, groupCollapsed) \
  V(GroupEnd, groupEnd)             \
  V(Clear, clear)                   \
  V(Count, count)                   \
  V(Assert, assert)                 \
  V(MarkTimeline, markTimeline)     \
  V(Profile, profile)               \
  V(ProfileEnd, profileEnd)         \
  V(Timeline, timeline)             \
  V(TimelineEnd, timelineEnd)       \
  V(Time, time)                     \
  V(TimeEnd, timeEnd)               \
  V(TimeStamp, timeStamp)

namespace {
void ConsoleCall(
    Isolate* isolate, internal::BuiltinArguments& args,
    void (debug::ConsoleDelegate::*func)(const v8::debug::ConsoleCallArguments&,
                                         const v8::debug::ConsoleContext&)) {
  CHECK(!isolate->has_pending_exception());
  CHECK(!isolate->has_scheduled_exception());
  if (!isolate->console_delegate()) return;
  HandleScope scope(isolate);
  debug::ConsoleCallArguments wrapper(args);
  Handle<Object> context_id_obj = JSObject::GetDataProperty(
      args.target(), isolate->factory()->console_context_id_symbol());
  int context_id =
      context_id_obj->IsSmi() ? Handle<Smi>::cast(context_id_obj)->value() : 0;
  Handle<Object> context_name_obj = JSObject::GetDataProperty(
      args.target(), isolate->factory()->console_context_name_symbol());
  Handle<String> context_name = context_name_obj->IsString()
                                    ? Handle<String>::cast(context_name_obj)
                                    : isolate->factory()->anonymous_string();
  (isolate->console_delegate()->*func)(
      wrapper,
      v8::debug::ConsoleContext(context_id, Utils::ToLocal(context_name)));
}
}  // namespace

#define CONSOLE_BUILTIN_IMPLEMENTATION(call, name)             \
  BUILTIN(Console##call) {                                     \
    ConsoleCall(isolate, args, &debug::ConsoleDelegate::call); \
    RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);            \
    return isolate->heap()->undefined_value();                 \
  }
CONSOLE_METHOD_LIST(CONSOLE_BUILTIN_IMPLEMENTATION)
#undef CONSOLE_BUILTIN_IMPLEMENTATION

namespace {
void InstallContextFunction(Handle<JSObject> target, const char* name,
                            Builtins::Name call, int context_id,
                            Handle<Object> context_name) {
  Factory* const factory = target->GetIsolate()->factory();

  Handle<Code> call_code(target->GetIsolate()->builtins()->builtin(call));

  Handle<String> name_string =
      Name::ToFunctionName(factory->InternalizeUtf8String(name))
          .ToHandleChecked();
  Handle<JSFunction> fun =
      factory->NewFunctionWithoutPrototype(name_string, call_code, SLOPPY);
  fun->shared()->set_native(true);
  fun->shared()->DontAdaptArguments();
  fun->shared()->set_length(1);

  JSObject::AddProperty(fun, factory->console_context_id_symbol(),
                        handle(Smi::FromInt(context_id), target->GetIsolate()),
                        NONE);
  if (context_name->IsString()) {
    JSObject::AddProperty(fun, factory->console_context_name_symbol(),
                          context_name, NONE);
  }
  JSObject::AddProperty(target, name_string, fun, NONE);
}
}  // namespace

BUILTIN(ConsoleContext) {
  HandleScope scope(isolate);

  Factory* const factory = isolate->factory();
  Handle<String> name = factory->InternalizeUtf8String("Context");
  Handle<JSFunction> cons = factory->NewFunction(name);
  Handle<JSObject> empty = factory->NewJSObject(isolate->object_function());
  JSFunction::SetPrototype(cons, empty);
  Handle<JSObject> context = factory->NewJSObject(cons, TENURED);
  DCHECK(context->IsJSObject());
  int id = isolate->last_console_context_id() + 1;
  isolate->set_last_console_context_id(id);

#define CONSOLE_BUILTIN_SETUP(call, name)                              \
  InstallContextFunction(context, #name, Builtins::kConsole##call, id, \
                         args.at(1));
  CONSOLE_METHOD_LIST(CONSOLE_BUILTIN_SETUP)
#undef CONSOLE_BUILTIN_SETUP

  return *context;
}

#undef CONSOLE_METHOD_LIST

}  // namespace internal
}  // namespace v8
