// 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;
}

std::unique_ptr<Command> ScriptDebuggerAgent::RunCommand(
    std::unique_ptr<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 nullptr;
  }

  // Take the command back out of the map and return it for fallback.
  command = std::move(pending_commands_.at(command_id));
  pending_commands_.erase(command_id);
  return 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
