// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/debug/runtime_component.h"

#include "base/bind.h"

namespace cobalt {
namespace debug {

namespace {
// File to load JavaScript runtime implementation from.
const char kScriptFile[] = "runtime.js";

// Definitions from the set specified here:
// https://developer.chrome.com/devtools/docs/protocol/1.1/runtime

// Command "methods" (names):
const char kCallFunctionOn[] = "Runtime.callFunctionOn";
const char kDisable[] = "Runtime.disable";
const char kEnable[] = "Runtime.enable";
const char kEvaluate[] = "Runtime.evaluate";
const char kGetProperties[] = "Runtime.getProperties";
const char kReleaseObject[] = "Runtime.releaseObject";
const char kReleaseObjectGroup[] = "Runtime.releaseObjectGroup";

// Event "methods" (names):
const char kExecutionContextCreated[] = "Runtime.executionContextCreated";

// Parameter names:
const char kContextFrameId[] = "context.frameId";
const char kContextId[] = "context.id";
const char kContextName[] = "context.name";

// Constant parameter values:
const char kContextFrameIdValue[] = "Cobalt";
const int kContextIdValue = 1;
const char kContextNameValue[] = "Cobalt";
}  // namespace

RuntimeComponent::RuntimeComponent(ComponentConnector* connector)
    : connector_(connector) {
  DCHECK(connector_);
  if (!connector_->RunScriptFile(kScriptFile)) {
    DLOG(WARNING) << "Cannot execute Runtime initialization script.";
  }

  connector_->AddCommand(
      kCallFunctionOn,
      base::Bind(&RuntimeComponent::CallFunctionOn, base::Unretained(this)));
  connector_->AddCommand(
      kDisable, base::Bind(&RuntimeComponent::Disable, base::Unretained(this)));
  connector_->AddCommand(
      kEnable, base::Bind(&RuntimeComponent::Enable, base::Unretained(this)));
  connector_->AddCommand(kEvaluate, base::Bind(&RuntimeComponent::Evaluate,
                                               base::Unretained(this)));
  connector_->AddCommand(
      kGetProperties,
      base::Bind(&RuntimeComponent::GetProperties, base::Unretained(this)));
  connector_->AddCommand(
      kReleaseObject,
      base::Bind(&RuntimeComponent::ReleaseObject, base::Unretained(this)));
  connector_->AddCommand(kReleaseObjectGroup,
                         base::Bind(&RuntimeComponent::ReleaseObjectGroup,
                                    base::Unretained(this)));
}

JSONObject RuntimeComponent::CallFunctionOn(const JSONObject& params) {
  return connector_->RunScriptCommand("runtime.callFunctionOn", params);
}

JSONObject RuntimeComponent::Disable(const JSONObject& params) {
  UNREFERENCED_PARAMETER(params);
  return JSONObject(new base::DictionaryValue());
}

JSONObject RuntimeComponent::Enable(const JSONObject& params) {
  UNREFERENCED_PARAMETER(params);
  OnExecutionContextCreated();
  return JSONObject(new base::DictionaryValue());
}

JSONObject RuntimeComponent::Evaluate(const JSONObject& params) {
  return connector_->RunScriptCommand("runtime.evaluate", params);
}

JSONObject RuntimeComponent::GetProperties(const JSONObject& params) {
  return connector_->RunScriptCommand("runtime.getProperties", params);
}

JSONObject RuntimeComponent::ReleaseObjectGroup(const JSONObject& params) {
  return connector_->RunScriptCommand("runtime.releaseObjectGroup", params);
}

JSONObject RuntimeComponent::ReleaseObject(const JSONObject& params) {
  return connector_->RunScriptCommand("runtime.releaseObject", params);
}

void RuntimeComponent::OnExecutionContextCreated() {
  JSONObject event(new base::DictionaryValue());
  event->SetString(kContextFrameId, kContextFrameIdValue);
  event->SetInteger(kContextId, kContextIdValue);
  event->SetString(kContextName, kContextNameValue);
  connector_->SendEvent(kExecutionContextCreated, event);
}

}  // namespace debug
}  // namespace cobalt
