// Copyright 2018 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/backend/script_debugger_agent.h"

#include <string>
#include <utility>

#include "base/strings/stringprintf.h"
#include "cobalt/debug/json_object.h"

namespace {
// State keys
constexpr char kScriptDebuggerState[] = "script_debugger";

// JSON attribute names
constexpr char kId[] = "id";
constexpr char kMethod[] = "method";
constexpr char kParams[] = "params";
}  // namespace

namespace cobalt {
namespace debug {
namespace backend {

ScriptDebuggerAgent::ScriptDebuggerAgent(
    DebugDispatcher* dispatcher, script::ScriptDebugger* script_debugger)
    : dispatcher_(dispatcher),
      script_debugger_(script_debugger),
      supported_domains_(script_debugger->SupportedProtocolDomains()) {}

void ScriptDebuggerAgent::Thaw(JSONObject agent_state) {
  for (auto domain : supported_domains_) {
    dispatcher_->AddDomain(domain, base::Bind(&ScriptDebuggerAgent::RunCommand,
                                              base::Unretained(this)));
  }
  std::string script_debugger_state;
  if (agent_state) {
    agent_state->GetString(kScriptDebuggerState, &script_debugger_state);
  }
  script_debugger_->Attach(script_debugger_state);
}

JSONObject ScriptDebuggerAgent::Freeze() {
  for (auto domain : supported_domains_) {
    dispatcher_->RemoveDomain(domain);
  }
  JSONObject agent_state(new base::DictionaryValue());
  std::string script_debugger_state = script_debugger_->Detach();
  agent_state->SetString(kScriptDebuggerState, script_debugger_state);
  return agent_state;
}

base::Optional<Command> ScriptDebuggerAgent::RunCommand(Command command) {
  DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

  // Use an internal ID to store the pending command until we get a response.
  int command_id = ++last_command_id_;

  JSONObject message(new base::DictionaryValue());
  message->SetInteger(kId, command_id);
  message->SetString(kMethod, command.GetMethod());
  JSONObject params = JSONParse(command.GetParams());
  if (params) {
    message->Set(kParams, std::move(params));
  }

  // Store the pending command before dispatching it so that we can find it if
  // the script debugger sends a synchronous response before returning.
  std::string method = command.GetMethod();
  pending_commands_.emplace(command_id, std::move(command));
  if (script_debugger_->DispatchProtocolMessage(method,
                                                JSONStringify(message))) {
    // The command has been dispatched; keep ownership of it in the map.
    return base::nullopt;
  }

  // Take the command back out of the map and return it for fallback.
  auto opt_command =
      base::make_optional(std::move(pending_commands_.at(command_id)));
  pending_commands_.erase(command_id);
  return opt_command;
}

void ScriptDebuggerAgent::SendCommandResponse(
    const std::string& json_response) {
  JSONObject response = JSONParse(json_response);

  // Strip the internal ID from the response, and get its value.
  int command_id = 0;
  response->GetInteger(kId, &command_id);
  response->Remove(kId, nullptr);

  // Use the stripped ID to lookup the command it's a response for.
  auto iter = pending_commands_.find(command_id);
  if (iter != pending_commands_.end()) {
    iter->second.SendResponse(response);
    pending_commands_.erase(iter);
  } else {
    DLOG(ERROR) << "Spurious debugger response: " << json_response;
  }
}

void ScriptDebuggerAgent::SendEvent(const std::string& json_event) {
  JSONObject event = JSONParse(json_event);

  std::string method;
  event->GetString(kMethod, &method);

  JSONObject params;
  base::Value* value = nullptr;
  base::DictionaryValue* dict_value = nullptr;
  if (event->Get(kParams, &value) && value->GetAsDictionary(&dict_value)) {
    params.reset(dict_value->DeepCopy());
  }

  dispatcher_->SendEvent(method, params);
}

}  // namespace backend
}  // namespace debug
}  // namespace cobalt
