// 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 "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 dispached; 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
