/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * 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 ART_ADBCONNECTION_ADBCONNECTION_H_
#define ART_ADBCONNECTION_ADBCONNECTION_H_

#include <jni.h>
#include <stdint.h>
#include <sys/socket.h>
#include <sys/un.h>

#include <limits>
#include <memory>
#include <vector>

#include "adbconnection/client.h"
#include "base/array_ref.h"
#include "base/mutex.h"
#include "runtime_callbacks.h"

namespace adbconnection {

static constexpr char kAdbConnectionThreadName[] = "ADB-JDWP Connection Control Thread";

// The default jdwp agent name.
static constexpr char kDefaultJdwpAgentName[] = "libjdwp.so";

class AdbConnectionState;

struct AdbConnectionDebuggerController : public art::DebuggerControlCallback {
  explicit AdbConnectionDebuggerController(AdbConnectionState* connection)
      : connection_(connection) {}

  // Begin running the debugger.
  void StartDebugger() override;

  // The debugger should begin shutting down since the runtime is ending.
  void StopDebugger() override;

  bool IsDebuggerConfigured() override;

 private:
  AdbConnectionState* connection_;
};

enum class DdmPacketType : uint8_t { kReply = 0x80, kCmd = 0x00, };

struct AdbConnectionDdmCallback : public art::DdmCallback {
  explicit AdbConnectionDdmCallback(AdbConnectionState* connection) : connection_(connection) {}

  void DdmPublishChunk(uint32_t type,
                       const art::ArrayRef<const uint8_t>& data)
      REQUIRES_SHARED(art::Locks::mutator_lock_);

 private:
  AdbConnectionState* connection_;
};

class AdbConnectionState {
 public:
  explicit AdbConnectionState(const std::string& name);
  ~AdbConnectionState();

  // Called on the listening thread to start dealing with new input. thr is used to attach the new
  // thread to the runtime.
  void RunPollLoop(art::Thread* self);

  // Sends ddms data over the socket, if there is one. This data is sent even if we haven't finished
  // hand-shaking yet.
  void PublishDdmData(uint32_t type, const art::ArrayRef<const uint8_t>& data);

  // Stops debugger threads during shutdown.
  void StopDebuggerThreads();

  // If StartDebuggerThreads was called successfully.
  bool DebuggerThreadsStarted() {
    return started_debugger_threads_;
  }

 private:
  uint32_t NextDdmId();

  void StartDebuggerThreads();

  // Tell adbd about the new runtime.
  bool SetupAdbConnection();

  std::string MakeAgentArg();

  void SendAgentFds(bool require_handshake);

  void CloseFds();

  void HandleDataWithoutAgent(art::Thread* self);

  void PerformHandshake();

  void AttachJdwpAgent(art::Thread* self);

  void NotifyDdms(bool active);

  void SendDdmPacket(uint32_t id,
                     DdmPacketType type,
                     uint32_t ddm_type,
                     art::ArrayRef<const uint8_t> data);

  std::string agent_name_;

  AdbConnectionDebuggerController controller_;
  AdbConnectionDdmCallback ddm_callback_;

  // Eventfd used to allow the StopDebuggerThreads function to wake up sleeping threads
  android::base::unique_fd sleep_event_fd_;

  // Context which wraps the socket which we use to talk to adbd.
  std::unique_ptr<AdbConnectionClientContext, void(*)(AdbConnectionClientContext*)> control_ctx_;

  // Socket that we use to talk to the agent (if it's loaded).
  android::base::unique_fd local_agent_control_sock_;

  // The fd of the socket the agent uses to talk to us. We need to keep it around in order to clean
  // it up when the runtime goes away.
  android::base::unique_fd remote_agent_control_sock_;

  // The fd that is forwarded through adb to the client. This is guarded by the
  // adb_write_event_fd_.
  android::base::unique_fd adb_connection_socket_;

  // The fd we send to the agent to let us synchronize access to the shared adb_connection_socket_.
  // This is also used as a general lock for the adb_connection_socket_ on any threads other than
  // the poll thread.
  android::base::unique_fd adb_write_event_fd_;

  std::atomic<bool> shutting_down_;

  // True if we have loaded the agent library.
  std::atomic<bool> agent_loaded_;

  // True if the dt_fd_forward transport is listening for a new communication channel.
  std::atomic<bool> agent_listening_;

  // True if the dt_fd_forward transport has the socket. If so we don't do anything to the agent or
  // the adb connection socket until connection goes away.
  std::atomic<bool> agent_has_socket_;

  std::atomic<bool> sent_agent_fds_;

  std::atomic<bool> performed_handshake_;

  bool notified_ddm_active_;

  std::atomic<uint32_t> next_ddm_id_;

  bool started_debugger_threads_;

  friend struct AdbConnectionDebuggerController;
};

}  // namespace adbconnection

#endif  // ART_ADBCONNECTION_ADBCONNECTION_H_
