/*
 * 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.
 */
#ifndef COBALT_DEBUG_JAVASCRIPT_DEBUGGER_COMPONENT_H_
#define COBALT_DEBUG_JAVASCRIPT_DEBUGGER_COMPONENT_H_

#include <map>
#include <string>
#include <vector>

#include "base/callback.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "cobalt/debug/component_connector.h"
#include "cobalt/debug/json_object.h"
#include "cobalt/script/call_frame.h"
#include "cobalt/script/scope.h"
#include "cobalt/script/script_debugger.h"
#include "cobalt/script/source_provider.h"

namespace cobalt {
namespace debug {

class JavaScriptDebuggerComponent : public script::ScriptDebugger::Delegate {
 public:
  explicit JavaScriptDebuggerComponent(ComponentConnector* connector);

  virtual ~JavaScriptDebuggerComponent();

  // ScriptDebugger::Delegate implementation.
  void OnScriptDebuggerDetach(const std::string& reason) OVERRIDE;
  void OnScriptDebuggerPause(scoped_ptr<script::CallFrame> call_frame) OVERRIDE;
  void OnScriptFailedToParse(
      scoped_ptr<script::SourceProvider> source_provider) OVERRIDE;
  void OnScriptParsed(
      scoped_ptr<script::SourceProvider> source_provider) OVERRIDE;

 private:
  // Map of SourceProvider pointers, keyed by string ID.
  typedef std::map<std::string, script::SourceProvider*> SourceProviderMap;

  // Logical breakpoint. A logical breakpoint exists independently of any
  // particular script, and will be checked each time a new script is parsed.
  // It can even correspond to multiple physical breakpoints, at least once we
  // support url regexes.
  struct Breakpoint {
    Breakpoint() : line_number(0), column_number(0) {}
    Breakpoint(const std::string& url, int line_number, int column_number)
        : url(url), line_number(line_number), column_number(column_number) {}
    std::string url;
    int line_number;
    int column_number;
    std::string condition;
  };

  // Script location, corresponding to physical breakpoint, etc.
  struct ScriptLocation {
    ScriptLocation(const std::string script_id, int line_number,
                   int column_number)
        : script_id(script_id),
          line_number(line_number),
          column_number(column_number) {}
    std::string script_id;
    int line_number;
    int column_number;
  };

  // Map of logical breakpoints, keyed by a string ID.
  typedef std::map<std::string, Breakpoint> BreakpointMap;

  JSONObject Enable(const JSONObject& params);
  JSONObject Disable(const JSONObject& params);

  // Gets the source of a specified script.
  JSONObject GetScriptSource(const JSONObject& params);

  // Code execution control commands.
  JSONObject Pause(const JSONObject& params);
  JSONObject Resume(const JSONObject& params);
  JSONObject SetBreakpointByUrl(const JSONObject& params);
  JSONObject SetPauseOnExceptions(const JSONObject& params);
  JSONObject StepInto(const JSONObject& params);
  JSONObject StepOut(const JSONObject& params);
  JSONObject StepOver(const JSONObject& params);

  // Creates a JSON object describing a single call frame.
  JSONObject CreateCallFrameData(
      const scoped_ptr<script::CallFrame>& call_frame);

  // Creates an array of JSON objects describing the call stack starting from
  // the specified call frame. Takes ownership of |call_frame|.
  JSONList CreateCallStackData(scoped_ptr<script::CallFrame> call_frame);

  // Creates a JSON object describing a single scope object.
  JSONObject CreateScopeData(const scoped_ptr<script::Scope>& scope);

  // Creates an array of JSON objects describing the scope chain starting from
  // the specified scope object. Takes ownership of |scope|.
  JSONList CreateScopeChainData(scoped_ptr<script::Scope> scope);

  // Called by |OnScriptFailedToParse| and |OnScriptParsed|.
  // Stores the source provider in |source_providers_| and dispatches the
  // specified event notification to the clients.
  void HandleScriptEvent(const std::string& method,
                         scoped_ptr<script::SourceProvider> source_provider);

  // Resolves a logical breakpoint into an array of source locations, one for
  // each matching script.
  void ResolveBreakpoint(const Breakpoint& breakpoint,
                         std::vector<ScriptLocation>* locations);

  // Sends a Debugger.paused event to the clients with call stack data.
  void SendPausedEvent(scoped_ptr<script::CallFrame> call_frame);

  // Sends a Debugger.resumed event to the clients with no parameters.
  void SendResumedEvent();

  // Helper object to connect to the debug server, etc.
  ComponentConnector* connector_;

  // Map of source providers with scoped deleter to clean up on destruction.
  SourceProviderMap source_providers_;
  STLValueDeleter<SourceProviderMap> source_providers_deleter_;

  // Map of logical breakpoints.
  BreakpointMap breakpoints_;
};

}  // namespace debug
}  // namespace cobalt

#endif  // COBALT_DEBUG_JAVASCRIPT_DEBUGGER_COMPONENT_H_
