// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

#include "vm/bootstrap_natives.h"
#include "vm/dart_api_impl.h"
#include "vm/datastream.h"
#include "vm/exceptions.h"
#include "vm/flags.h"
#include "vm/growable_array.h"
#include "vm/kernel_isolate.h"
#include "vm/message.h"
#include "vm/message_handler.h"
#include "vm/message_snapshot.h"
#include "vm/native_entry.h"
#include "vm/object.h"
#include "vm/port.h"
#include "vm/service_event.h"
#include "vm/service_isolate.h"
#include "vm/symbols.h"

namespace dart {

DECLARE_FLAG(bool, trace_service);

#ifndef PRODUCT
class RegisterRunningIsolatesVisitor : public IsolateVisitor {
 public:
  explicit RegisterRunningIsolatesVisitor(Thread* thread)
      : IsolateVisitor(),
        zone_(thread->zone()),
        register_function_(Function::Handle(thread->zone())),
        service_isolate_(thread->isolate()) {}

  virtual void VisitIsolate(Isolate* isolate) {
    isolate_ports_.Add(isolate->main_port());
    isolate_names_.Add(&String::Handle(zone_, String::New(isolate->name())));
    isolate->set_is_service_registered(true);
  }

  void RegisterIsolates() {
    ServiceIsolate::RegisterRunningIsolates(isolate_ports_, isolate_names_);
  }

 private:
  Zone* zone_;
  GrowableArray<Dart_Port> isolate_ports_;
  GrowableArray<const String*> isolate_names_;
  Function& register_function_;
  Isolate* service_isolate_;
};
#endif  // !PRODUCT

DEFINE_NATIVE_ENTRY(VMService_SendIsolateServiceMessage, 0, 2) {
#ifndef PRODUCT
  GET_NON_NULL_NATIVE_ARGUMENT(SendPort, sp, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(1));

  // Set the type of the OOB message.
  message.SetAt(0,
                Smi::Handle(thread->zone(), Smi::New(Message::kServiceOOBMsg)));

  // Serialize message.
  // TODO(turnidge): Throw an exception when the return value is false?
  bool result = PortMap::PostMessage(WriteMessage(
      /* same_group */ false, message, sp.Id(), Message::kOOBPriority));
  return Bool::Get(result).ptr();
#else
  return Object::null();
#endif
}

DEFINE_NATIVE_ENTRY(VMService_SendRootServiceMessage, 0, 1) {
#ifndef PRODUCT
  GET_NON_NULL_NATIVE_ARGUMENT(Array, message, arguments->NativeArgAt(0));
  return Service::HandleRootMessage(message);
#endif
  return Object::null();
}

DEFINE_NATIVE_ENTRY(VMService_OnStart, 0, 0) {
#ifndef PRODUCT
  if (FLAG_trace_service) {
    OS::PrintErr("vm-service: Booting dart:vmservice library.\n");
  }
  // Boot the dart:vmservice library.
  ServiceIsolate::BootVmServiceLibrary();
  // Register running isolates with service.
  RegisterRunningIsolatesVisitor register_isolates(thread);
  if (FLAG_trace_service) {
    OS::PrintErr("vm-service: Registering running isolates.\n");
  }
  Isolate::VisitIsolates(&register_isolates);
  register_isolates.RegisterIsolates();
#endif
  return Object::null();
}

DEFINE_NATIVE_ENTRY(VMService_OnExit, 0, 0) {
#ifndef PRODUCT
  if (FLAG_trace_service) {
    OS::PrintErr("vm-service: processed exit message.\n");
    OS::PrintErr("vm-service: has live ports: %s\n",
                 isolate->HasLivePorts() ? "yes" : "no");
  }
#endif
  return Object::null();
}

DEFINE_NATIVE_ENTRY(VMService_OnServerAddressChange, 0, 1) {
#ifndef PRODUCT
  GET_NATIVE_ARGUMENT(String, address, arguments->NativeArgAt(0));
  if (address.IsNull()) {
    ServiceIsolate::SetServerAddress(nullptr);
  } else {
    ServiceIsolate::SetServerAddress(address.ToCString());
  }
#endif
  return Object::null();
}

DEFINE_NATIVE_ENTRY(VMService_ListenStream, 0, 2) {
#ifndef PRODUCT
  GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0));
  GET_NON_NULL_NATIVE_ARGUMENT(Bool, include_privates,
                               arguments->NativeArgAt(1));
  bool result =
      Service::ListenStream(stream_id.ToCString(), include_privates.value());
  return Bool::Get(result).ptr();
#else
  return Object::null();
#endif
}

DEFINE_NATIVE_ENTRY(VMService_CancelStream, 0, 1) {
#ifndef PRODUCT
  GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0));
  Service::CancelStream(stream_id.ToCString());
#endif
  return Object::null();
}

}  // namespace dart
