// Copyright 2016 Google Inc. 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/javascript_debugger_component.h"

#include "base/bind.h"
#include "base/optional.h"
#include "base/stringprintf.h"
#include "base/values.h"

namespace cobalt {
namespace debug {

namespace {
// Command, parameter and event names as specified by the protocol:
// https://developer.chrome.com/devtools/docs/protocol/1.1/debugger

// Commands.
const char kDisable[] = "Debugger.disable";
const char kEnable[] = "Debugger.enable";
const char kGetScriptSource[] = "Debugger.getScriptSource";
const char kPause[] = "Debugger.pause";
const char kResume[] = "Debugger.resume";
const char kSetBreakpointByUrl[] = "Debugger.setBreakpointByUrl";
const char kSetPauseOnExceptions[] = "Debugger.setPauseOnExceptions";
const char kStepInto[] = "Debugger.stepInto";
const char kStepOut[] = "Debugger.stepOut";
const char kStepOver[] = "Debugger.stepOver";

// Parameter names.
const char kCallFrameId[] = "callFrameId";
const char kCallFrames[] = "callFrames";
const char kColumnNumber[] = "columnNumber";
const char kErrorLine[] = "errorLine";
const char kErrorMessage[] = "errorMessage";
const char kFunctionName[] = "functionName";
const char kLineNumber[] = "lineNumber";
const char kLocationColumnNumber[] = "location.columnNumber";
const char kLocationLineNumber[] = "location.lineNumber";
const char kLocationScriptId[] = "location.scriptId";
const char kObject[] = "object";
const char kReason[] = "reason";
const char kScopeChain[] = "scopeChain";
const char kScriptId[] = "scriptId";
const char kState[] = "state";
const char kThis[] = "this";
const char kType[] = "type";
const char kUrl[] = "url";

// Parameter values.
const char kDebugCommand[] = "debugCommand";

// Result parameters.
const char kBreakpointId[] = "result.breakpointId";
const char kLocations[] = "result.locations";
const char kScriptSource[] = "result.scriptSource";

// Events.
const char kPaused[] = "Debugger.paused";
const char kResumed[] = "Debugger.resumed";
const char kScriptFailedToParse[] = "Debugger.scriptFailedToParse";
const char kScriptParsed[] = "Debugger.scriptParsed";

// Construct a unique breakpoint id from url and source location.
// Use the same format as Chrome.
std::string BreakpointId(const std::string url, int line_number,
                         int column_number) {
  return base::StringPrintf("%s:%d:%d", url.c_str(), line_number,
                            column_number);
}

}  // namespace

JavaScriptDebuggerComponent::JavaScriptDebuggerComponent(
    ComponentConnector* connector)
    : connector_(connector), source_providers_deleter_(&source_providers_) {
  DCHECK(connector_);
  connector_->AddCommand(kDisable,
                         base::Bind(&JavaScriptDebuggerComponent::Disable,
                                    base::Unretained(this)));
  connector_->AddCommand(
      kEnable,
      base::Bind(&JavaScriptDebuggerComponent::Enable, base::Unretained(this)));
  connector_->AddCommand(
      kGetScriptSource,
      base::Bind(&JavaScriptDebuggerComponent::GetScriptSource,
                 base::Unretained(this)));
  connector_->AddCommand(kPause, base::Bind(&JavaScriptDebuggerComponent::Pause,
                                            base::Unretained(this)));
  connector_->AddCommand(
      kResume,
      base::Bind(&JavaScriptDebuggerComponent::Resume, base::Unretained(this)));
  connector_->AddCommand(kStepInto,
                         base::Bind(&JavaScriptDebuggerComponent::StepInto,
                                    base::Unretained(this)));
  connector_->AddCommand(
      kSetBreakpointByUrl,
      base::Bind(&JavaScriptDebuggerComponent::SetBreakpointByUrl,
                 base::Unretained(this)));
  connector_->AddCommand(
      kSetPauseOnExceptions,
      base::Bind(&JavaScriptDebuggerComponent::SetPauseOnExceptions,
                 base::Unretained(this)));
  connector_->AddCommand(kStepOut,
                         base::Bind(&JavaScriptDebuggerComponent::StepOut,
                                    base::Unretained(this)));
  connector_->AddCommand(kStepOver,
                         base::Bind(&JavaScriptDebuggerComponent::StepOver,
                                    base::Unretained(this)));
}

JavaScriptDebuggerComponent::~JavaScriptDebuggerComponent() {}

JSONObject JavaScriptDebuggerComponent::Enable(const JSONObject& params) {
  UNREFERENCED_PARAMETER(params);
  DCHECK(connector_->script_debugger());
  connector_->script_debugger()->Attach();
  return JSONObject(new base::DictionaryValue());
}

JSONObject JavaScriptDebuggerComponent::Disable(const JSONObject& params) {
  UNREFERENCED_PARAMETER(params);
  DCHECK(connector_->script_debugger());
  connector_->script_debugger()->Detach();
  return JSONObject(new base::DictionaryValue());
}

JSONObject JavaScriptDebuggerComponent::GetScriptSource(
    const JSONObject& params) {
  // Get the scriptId from the parameters.
  std::string script_id;
  bool got_script_id = params->GetString(kScriptId, &script_id);
  if (!got_script_id) {
    return connector_->ErrorResponse("No scriptId specified in parameters.");
  }

  // Find the source provider with a matching scriptId.
  SourceProviderMap::iterator it = source_providers_.find(script_id);
  if (it == source_providers_.end()) {
    return connector_->ErrorResponse(
        "No script found with specified scriptId.");
  }
  script::SourceProvider* source_provider = it->second;
  DCHECK(source_provider);

  // Build and return the result.
  JSONObject result(new base::DictionaryValue());
  result->SetString(kScriptSource, source_provider->GetScriptSource());
  return result.Pass();
}

JSONObject JavaScriptDebuggerComponent::Pause(const JSONObject& params) {
  UNREFERENCED_PARAMETER(params);
  DCHECK(connector_->script_debugger());
  connector_->script_debugger()->Pause();
  return JSONObject(new base::DictionaryValue());
}

JSONObject JavaScriptDebuggerComponent::Resume(const JSONObject& params) {
  UNREFERENCED_PARAMETER(params);
  DCHECK(connector_->script_debugger());
  DCHECK(connector_->server());
  connector_->script_debugger()->Resume();
  connector_->server()->SetPaused(false);
  return JSONObject(new base::DictionaryValue());
}

JSONObject JavaScriptDebuggerComponent::SetBreakpointByUrl(
    const JSONObject& params) {
  DCHECK(connector_->script_debugger());
  DCHECK(connector_->server());

  std::string url;
  bool got_url = params->GetString(kUrl, &url);
  if (!got_url) {
    return connector_->ErrorResponse("Breakpoint URL must be specified.");
  }

  // TODO: Should also handle setting of breakpoint by urlRegex

  int line_number;
  bool got_line_number = params->GetInteger(kLineNumber, &line_number);
  if (!got_line_number) {
    return connector_->ErrorResponse("Line number must be specified.");
  }
  // If no column number is specified, just default to 0.
  int column_number = 0;
  params->GetInteger(kColumnNumber, &column_number);

  // TODO: Should also handle condition and isAntibreakpoint.

  // Create a new logical breakpoint and store it in our map.
  const std::string breakpoint_id =
      BreakpointId(url, line_number, column_number);
  Breakpoint breakpoint(url, line_number, column_number);
  breakpoints_[breakpoint_id] = breakpoint;

  // Check the logical breakpoint against all currently loaded source providers
  // and get an array of matching breakpoint locations.
  std::vector<ScriptLocation> locations;
  ResolveBreakpoint(breakpoint, &locations);

  // Construct a result object from the logical breakpoint id and resolved
  // source locations.
  JSONObject result(new base::DictionaryValue());
  result->SetString(kBreakpointId, breakpoint_id);
  JSONList location_objects(new base::ListValue());
  for (std::vector<ScriptLocation>::const_iterator it = locations.begin();
       it != locations.end(); ++it) {
    JSONObject location(new base::DictionaryValue());
    location->SetString(kScriptId, it->script_id);
    location->SetInteger(kLineNumber, it->line_number);
    location->SetInteger(kColumnNumber, it->column_number);
    location_objects->Append(location.release());
  }
  result->Set(kLocations, location_objects.release());
  return result.Pass();
}

JSONObject JavaScriptDebuggerComponent::SetPauseOnExceptions(
    const JSONObject& params) {
  DCHECK(connector_->script_debugger());
  DCHECK(connector_->server());

  std::string state;
  DCHECK(params->GetString(kState, &state));
  if (state == "all") {
    connector_->script_debugger()->SetPauseOnExceptions(
        script::ScriptDebugger::kAll);
  } else if (state == "none") {
    connector_->script_debugger()->SetPauseOnExceptions(
        script::ScriptDebugger::kNone);
  } else if (state == "uncaught") {
    connector_->script_debugger()->SetPauseOnExceptions(
        script::ScriptDebugger::kUncaught);
  } else {
    NOTREACHED();
  }
  return JSONObject(new base::DictionaryValue());
}

JSONObject JavaScriptDebuggerComponent::StepInto(const JSONObject& params) {
  UNREFERENCED_PARAMETER(params);
  DCHECK(connector_->script_debugger());
  DCHECK(connector_->server());
  connector_->script_debugger()->StepInto();
  connector_->server()->SetPaused(false);
  return JSONObject(new base::DictionaryValue());
}

JSONObject JavaScriptDebuggerComponent::StepOut(const JSONObject& params) {
  UNREFERENCED_PARAMETER(params);
  DCHECK(connector_->script_debugger());
  DCHECK(connector_->server());
  connector_->script_debugger()->StepOut();
  connector_->server()->SetPaused(false);
  return JSONObject(new base::DictionaryValue());
}

JSONObject JavaScriptDebuggerComponent::StepOver(const JSONObject& params) {
  UNREFERENCED_PARAMETER(params);
  DCHECK(connector_->script_debugger());
  DCHECK(connector_->server());
  connector_->script_debugger()->StepOver();
  connector_->server()->SetPaused(false);
  return JSONObject(new base::DictionaryValue());
}

void JavaScriptDebuggerComponent::OnScriptDebuggerDetach(
    const std::string& reason) {
  DLOG(INFO) << "JavaScript debugger detached: " << reason;
}

void JavaScriptDebuggerComponent::OnScriptDebuggerPause(
    scoped_ptr<script::CallFrame> call_frame) {
  // Notify the clients we're about to pause.
  SendPausedEvent(call_frame.Pass());

  // Tell the debug server to enter paused state - block this thread.
  DCHECK(connector_->server());
  connector_->server()->SetPaused(true);

  // Notify the clients we've resumed.
  SendResumedEvent();
}

void JavaScriptDebuggerComponent::OnScriptFailedToParse(
    scoped_ptr<script::SourceProvider> source_provider) {
  DCHECK(source_provider);
  HandleScriptEvent(kScriptFailedToParse, source_provider.Pass());
}

void JavaScriptDebuggerComponent::OnScriptParsed(
    scoped_ptr<script::SourceProvider> source_provider) {
  DCHECK(source_provider);
  HandleScriptEvent(kScriptParsed, source_provider.Pass());
}

JSONObject JavaScriptDebuggerComponent::CreateCallFrameData(
    const scoped_ptr<script::CallFrame>& call_frame) {
  DCHECK(call_frame);

  // Create the JSON object and add the data for this call frame.
  JSONObject call_frame_data(new base::DictionaryValue());
  call_frame_data->SetString(kCallFrameId, call_frame->GetCallFrameId());
  call_frame_data->SetString(kFunctionName, call_frame->GetFunctionName());

  // Offset the line number according to the start line of the source.
  const std::string script_id = call_frame->GetScriptId();
  int line_number = call_frame->GetLineNumber();
  DCHECK(source_providers_[script_id]);
  base::optional<int> start_line = source_providers_[script_id]->GetStartLine();
  line_number -= start_line.value_or(1);

  // Add the location data.
  call_frame_data->SetString(kLocationScriptId, script_id);
  call_frame_data->SetInteger(kLocationLineNumber, line_number);
  base::optional<int> column_number = call_frame->GetColumnNumber();
  if (column_number) {
    call_frame_data->SetInteger(kLocationColumnNumber, column_number.value());
  }

  // Add the scope chain data.
  JSONList scope_chain_data(CreateScopeChainData(call_frame->GetScopeChain()));
  call_frame_data->Set(kScopeChain, scope_chain_data.release());

  // Add the "this" object data.
  const script::OpaqueHandleHolder* this_object = call_frame->GetThis();
  if (this_object) {
    JSONObject this_object_data(connector_->CreateRemoteObject(this_object));
    call_frame_data->Set(kThis, this_object_data.release());
  }

  return call_frame_data.Pass();
}

JSONList JavaScriptDebuggerComponent::CreateCallStackData(
    scoped_ptr<script::CallFrame> call_frame) {
  JSONList call_frame_list(new base::ListValue());

  // Consume the scoped CallFrame objects as we iterate over them.
  while (call_frame) {
    JSONObject call_frame_data(CreateCallFrameData(call_frame));
    DCHECK(call_frame_data);
    call_frame_list->Append(call_frame_data.release());
    scoped_ptr<script::CallFrame> next_call_frame(call_frame->GetCaller());
    call_frame = next_call_frame.Pass();
  }

  return call_frame_list.Pass();
}

JSONObject JavaScriptDebuggerComponent::CreateScopeData(
    const scoped_ptr<script::Scope>& scope) {
  DCHECK(scope);
  const script::OpaqueHandleHolder* scope_object = scope->GetObject();
  JSONObject scope_data(new base::DictionaryValue());
  scope_data->Set(kObject,
                  connector_->CreateRemoteObject(scope_object).release());
  scope_data->SetString(kType, script::Scope::TypeToString(scope->GetType()));
  return scope_data.Pass();
}

JSONList JavaScriptDebuggerComponent::CreateScopeChainData(
    scoped_ptr<script::Scope> scope) {
  JSONList scope_chain_list(new base::ListValue());

  // Consume the scoped Scope objects as we iterate over them.
  while (scope) {
    JSONObject scope_data(CreateScopeData(scope));
    DCHECK(scope_data);
    scope_chain_list->Append(scope_data.release());
    scoped_ptr<script::Scope> next_scope(scope->GetNext());
    scope = next_scope.Pass();
  }

  return scope_chain_list.Pass();
}

void JavaScriptDebuggerComponent::HandleScriptEvent(
    const std::string& method,
    scoped_ptr<script::SourceProvider> source_provider) {
  DCHECK(source_provider);

  // Send the event notification to the debugger clients.
  JSONObject params(new base::DictionaryValue());
  params->SetString(kScriptId, source_provider->GetScriptId());
  params->SetString(kUrl, source_provider->GetUrl());
  base::optional<int> error_line = source_provider->GetErrorLine();
  if (error_line) {
    DCHECK_EQ(method, kScriptFailedToParse);
    params->SetInteger(kErrorLine, error_line.value());
  }
  base::optional<std::string> error_message =
      source_provider->GetErrorMessage();
  if (error_message) {
    DCHECK_EQ(method, kScriptFailedToParse);
    params->SetString(kErrorMessage, error_message.value());
  }
  connector_->SendEvent(method, params);

  // Store the raw pointer to the source provider in the map.
  // The values in the map will be deleted on destruction by
  // |source_providers_deleter_|.
  const std::string script_id = source_provider->GetScriptId();
  SourceProviderMap::iterator it = source_providers_.find(script_id);
  if (it != source_providers_.end()) {
    delete it->second;
  }
  source_providers_[script_id] = source_provider.release();
}

void JavaScriptDebuggerComponent::ResolveBreakpoint(
    const Breakpoint& breakpoint, std::vector<ScriptLocation>* locations) {
  for (SourceProviderMap::iterator it = source_providers_.begin();
       it != source_providers_.end(); ++it) {
    script::SourceProvider* script = it->second;
    if (script->GetUrl() == breakpoint.url) {
      connector_->script_debugger()->SetBreakpoint(
          script->GetScriptId(),
          breakpoint.line_number + script->GetStartLine().value_or(1),
          breakpoint.column_number);
      locations->push_back(ScriptLocation(script->GetScriptId(),
                                          breakpoint.line_number,
                                          breakpoint.column_number));
    }
  }
}

void JavaScriptDebuggerComponent::SendPausedEvent(
    scoped_ptr<script::CallFrame> call_frame) {
  std::string event_method = kPaused;
  JSONObject event_params(new base::DictionaryValue());
  JSONList call_stack_data(CreateCallStackData(call_frame.Pass()));
  DCHECK(call_stack_data);
  event_params->Set(kCallFrames, call_stack_data.release());
  event_params->SetString(kReason, kDebugCommand);
  connector_->SendEvent(event_method, event_params);
}

void JavaScriptDebuggerComponent::SendResumedEvent() {
  // Send the event to the clients. No parameters.
  std::string event_method = kResumed;
  scoped_ptr<base::DictionaryValue> event_params(new base::DictionaryValue());
  connector_->SendEvent(event_method, event_params);
}

}  // namespace debug
}  // namespace cobalt
