// Copyright 2006-2008 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Google Inc. nor the names of its
//       contributors may be used to endorse or promote products derived
//       from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#ifndef V8_DEBUG_AGENT_H_
#define V8_DEBUG_AGENT_H_

#ifdef ENABLE_DEBUGGER_SUPPORT
#include "../include/v8-debug.h"
#include "platform.h"

namespace v8 {
namespace internal {

// Forward decelrations.
class DebuggerAgentSession;
class Socket;


// Debugger agent which starts a socket listener on the debugger port and
// handles connection from a remote debugger.
class DebuggerAgent: public Thread {
 public:
  DebuggerAgent(Isolate* isolate, const char* name, int port);
  ~DebuggerAgent();

  void Shutdown();
  void WaitUntilListening();

  Isolate* isolate() { return isolate_; }

 private:
  void Run();
  void CreateSession(Socket* socket);
  void DebuggerMessage(const v8::Debug::Message& message);
  void CloseSession();
  void OnSessionClosed(DebuggerAgentSession* session);

  Isolate* isolate_;
  SmartArrayPointer<const char> name_;  // Name of the embedding application.
  int port_;  // Port to use for the agent.
  Socket* server_;  // Server socket for listen/accept.
  bool terminate_;  // Termination flag.
  RecursiveMutex session_access_;  // Mutex guarding access to session_.
  DebuggerAgentSession* session_;  // Current active session if any.
  Semaphore terminate_now_;  // Semaphore to signal termination.
  Semaphore listening_;

  friend class DebuggerAgentSession;
  friend void DebuggerAgentMessageHandler(const v8::Debug::Message& message);

  DISALLOW_COPY_AND_ASSIGN(DebuggerAgent);
};


// Debugger agent session. The session receives requests from the remote
// debugger and sends debugger events/responses to the remote debugger.
class DebuggerAgentSession: public Thread {
 public:
  DebuggerAgentSession(DebuggerAgent* agent, Socket* client)
      : Thread("v8:DbgAgntSessn"),
        agent_(agent), client_(client) {}

  void DebuggerMessage(Vector<uint16_t> message);
  void Shutdown();

 private:
  void Run();

  void DebuggerMessage(Vector<char> message);

  DebuggerAgent* agent_;
  Socket* client_;

  DISALLOW_COPY_AND_ASSIGN(DebuggerAgentSession);
};


// Utility methods factored out to be used by the D8 shell as well.
class DebuggerAgentUtil {
 public:
  static const char* const kContentLength;

  static SmartArrayPointer<char> ReceiveMessage(Socket* conn);
  static bool SendConnectMessage(Socket* conn, const char* embedding_host);
  static bool SendMessage(Socket* conn, const Vector<uint16_t> message);
  static bool SendMessage(Socket* conn, const v8::Handle<v8::String> message);
  static int ReceiveAll(Socket* conn, char* data, int len);
};

} }  // namespace v8::internal

#endif  // ENABLE_DEBUGGER_SUPPORT

#endif  // V8_DEBUG_AGENT_H_
