/*
 * Copyright (C) 2015 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.
 */

#if !defined(__ANDROID_RECOVERY__)
#define TRACE_TAG JDWP

#include "sysdeps.h"

#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <unistd.h>

#include <list>
#include <memory>
#include <thread>
#include <vector>

#include <adbconnection/process_info.h>
#include <adbconnection/server.h>
#include <android-base/cmsg.h>
#include <android-base/unique_fd.h>

#include "adb.h"
#include "adb_io.h"
#include "adb_unique_fd.h"
#include "adb_utils.h"
#include "app_processes.pb.h"

using android::base::borrowed_fd;
using android::base::unique_fd;

/* here's how these things work.

   when adbd starts, it creates a unix server socket
   named @jdwp-control (@ is a shortcut for "first byte is zero"
   to use the private namespace instead of the file system)

   when a new JDWP daemon thread starts in a new VM process, it creates
   a connection to @jdwp-control to announce its availability.


     JDWP thread                             @jdwp-control
         |                                         |
         |------------------------------->         |
         | hello I'm in process <pid>              |
         |                                         |
         |                                         |

    the connection is kept alive. it will be closed automatically if
    the JDWP process terminates (this allows adbd to detect dead
    processes).

    adbd thus maintains a list of "active" JDWP processes. it can send
    its content to clients through the "device:debug-ports" service,
    or even updates through the "device:track-debug-ports" service.

    when a debugger wants to connect, it simply runs the command
    equivalent to  "adb forward tcp:<hostport> jdwp:<pid>"

    "jdwp:<pid>" is a new forward destination format used to target
    a given JDWP process on the device. when sutch a request arrives,
    adbd does the following:

      - first, it calls socketpair() to create a pair of equivalent
        sockets.

      - it attaches the first socket in the pair to a local socket
        which is itself attached to the transport's remote socket:


      - it sends the file descriptor of the second socket directly
        to the JDWP process with the help of sendmsg()


     JDWP thread                             @jdwp-control
         |                                         |
         |                  <----------------------|
         |           OK, try this file descriptor  |
         |                                         |
         |                                         |

   then, the JDWP thread uses this new socket descriptor as its
   pass-through connection to the debugger (and receives the
   JDWP-Handshake message, answers to it, etc...)

   this gives the following graphics:
                    ____________________________________
                   |                                    |
                   |          ADB Server (host)         |
                   |                                    |
        Debugger <---> LocalSocket <----> RemoteSocket  |
                   |                           ^^       |
                   |___________________________||_______|
                                               ||
                                     Transport ||
           (TCP for emulator - USB for device) ||
                                               ||
                    ___________________________||_______
                   |                           ||       |
                   |          ADBD  (device)   ||       |
                   |                           VV       |
         JDWP <======> LocalSocket <----> RemoteSocket  |
                   |                                    |
                   |____________________________________|

    due to the way adb works, this doesn't need a special socket
    type or fancy handling of socket termination if either the debugger
    or the JDWP process closes the connection.

    THIS IS THE SIMPLEST IMPLEMENTATION I COULD FIND, IF YOU HAPPEN
    TO HAVE A BETTER IDEA, LET ME KNOW - Digit

**********************************************************************/

/** JDWP PID List Support Code
 ** for each JDWP process, we record its pid and its connected socket
 **/

enum class TrackerKind {
    kJdwp,
    kApp,
};

static void jdwp_process_event(int socket, unsigned events, void* _proc);
static void jdwp_process_list_updated(void);
static void app_process_list_updated(void);

struct JdwpProcess;
static auto& _jdwp_list = *new std::list<std::unique_ptr<JdwpProcess>>();

struct JdwpProcess {
    JdwpProcess(unique_fd socket, ProcessInfo process) {
        CHECK(process.pid != 0);

        this->socket = socket;
        this->process = process;
        this->fde = fdevent_create(socket.release(), jdwp_process_event, this);

        if (!this->fde) {
            LOG(FATAL) << "could not create fdevent for new JDWP process";
        }
    }

    ~JdwpProcess() {
        if (this->socket >= 0) {
            adb_shutdown(this->socket);
            this->socket = -1;
        }

        if (this->fde) {
            fdevent_destroy(this->fde);
            this->fde = nullptr;
        }

        out_fds.clear();
    }

    void RemoveFromList() {
        auto pred = [this](const auto& proc) { return proc.get() == this; };
        _jdwp_list.remove_if(pred);
    }

    borrowed_fd socket = -1;
    ProcessInfo process;
    fdevent* fde = nullptr;

    // When a jdwp:<PID> request arrives, we create a socketpair and immediately
    // return one end to the requester. The other end is "staged" in this queue.
    // The next time @jdwp-control becomes FDE_WRITE, we send the back() fd (it is
    // received on the other end of @jdwp-control by ART) and pop it. This queue
    // should almost always be empty if ART reads() from @jdwp-control properly.
    std::vector<unique_fd> out_fds;
};

// Populate the list of processes for "track-jdwp" service.
static size_t jdwp_process_list(char* buffer, size_t bufferlen) {
    std::string temp;

    for (auto& proc : _jdwp_list) {
        if (!proc->process.debuggable) continue;
        std::string next = std::to_string(proc->process.pid) + "\n";
        if (temp.length() + next.length() > bufferlen) {
            D("truncating JDWP process list (max len = %zu)", bufferlen);
            break;
        }
        temp.append(next);
    }

    memcpy(buffer, temp.data(), temp.length());
    return temp.length();
}

// Populate the list of processes for "track-app" service.
// The list is a protobuf message in the binary format for efficiency.
static size_t app_process_list(char* buffer, size_t bufferlen) {
    adb::proto::AppProcesses output;  // result that's guaranteed to fit in the given buffer
    adb::proto::AppProcesses temp;    // temporary result that may be longer than the given buffer
    std::string serialized_message;

    for (auto& proc : _jdwp_list) {
        if (!proc->process.debuggable && !proc->process.profileable) continue;
        auto* entry = temp.add_process();
        entry->set_pid(proc->process.pid);
        entry->set_debuggable(proc->process.debuggable);
        entry->set_profileable(proc->process.profileable);
        entry->set_architecture(proc->process.arch_name, proc->process.arch_name_length);
        temp.SerializeToString(&serialized_message);
        if (serialized_message.size() > bufferlen) {
            D("truncating app process list (max len = %zu)", bufferlen);
            break;
        }
        output = temp;
    }
    output.SerializeToString(&serialized_message);
    memcpy(buffer, serialized_message.data(), serialized_message.length());
    return serialized_message.length();
}

// Populate the list of processes for either "track-jdwp" or "track-app" services,
// depending on the given kind.
static size_t process_list(TrackerKind kind, char* buffer, size_t bufferlen) {
    switch (kind) {
        case TrackerKind::kJdwp:
            return jdwp_process_list(buffer, bufferlen);
        case TrackerKind::kApp:
            return app_process_list(buffer, bufferlen);
    }
}

static size_t process_list_msg(TrackerKind kind, char* buffer, size_t bufferlen) {
    // Message is length-prefixed with 4 hex digits in ASCII.
    static constexpr size_t header_len = 4;
    if (bufferlen < header_len) {
        LOG(FATAL) << "invalid JDWP process list buffer size: " << bufferlen;
    }

    char head[header_len + 1];
    size_t len = process_list(kind, buffer + header_len, bufferlen - header_len);
    snprintf(head, sizeof head, "%04zx", len);
    memcpy(buffer, head, header_len);
    return len + header_len;
}

static void jdwp_process_event(int socket, unsigned events, void* _proc) {
    JdwpProcess* proc = reinterpret_cast<JdwpProcess*>(_proc);
    CHECK_EQ(socket, proc->socket.get());

    if (events & FDE_READ) {
        // We already have the PID, if we can read from the socket, we've probably hit EOF.
        D("terminating JDWP connection %" PRId64, proc->process.pid);
        goto CloseProcess;
    }

    if (events & FDE_WRITE) {
        D("trying to send fd to JDWP process (count = %zu)", proc->out_fds.size());
        CHECK(!proc->out_fds.empty());

        int fd = proc->out_fds.back().get();
        if (android::base::SendFileDescriptors(socket, "", 1, fd) != 1) {
            D("sending new file descriptor to JDWP %" PRId64 " failed: %s", proc->process.pid,
              strerror(errno));
            goto CloseProcess;
        }

        D("sent file descriptor %d to JDWP process %" PRId64, fd, proc->process.pid);

        proc->out_fds.pop_back();
        if (proc->out_fds.empty()) {
            fdevent_del(proc->fde, FDE_WRITE);
        }
    }

    return;

CloseProcess:
    bool debuggable = proc->process.debuggable;
    bool profileable = proc->process.profileable;
    proc->RemoveFromList();
    if (debuggable) jdwp_process_list_updated();
    if (debuggable || profileable) app_process_list_updated();
}

unique_fd create_jdwp_connection_fd(int pid) {
    D("looking for pid %d in JDWP process list", pid);

    for (auto& proc : _jdwp_list) {
        // Don't allow JDWP connection to a non-debuggable process.
        if (!proc->process.debuggable) continue;
        if (proc->process.pid == static_cast<uint64_t>(pid)) {
            int fds[2];

            if (adb_socketpair(fds) < 0) {
                D("%s: socket pair creation failed: %s", __FUNCTION__, strerror(errno));
                return unique_fd{};
            }
            D("socketpair: (%d,%d)", fds[0], fds[1]);

            proc->out_fds.emplace_back(fds[1]);
            if (proc->out_fds.size() == 1) {
                fdevent_add(proc->fde, FDE_WRITE);
            }

            return unique_fd{fds[0]};
        }
    }
    D("search failed !!");
    return unique_fd{};
}

/** "jdwp" local service implementation
 ** this simply returns the list of known JDWP process pids
 **/

struct JdwpSocket : public asocket {
    bool pass = false;
};

static void jdwp_socket_close(asocket* s) {
    D("LS(%d): closing jdwp socket", s->id);

    if (s->peer) {
        D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
        s->peer->peer = nullptr;
        s->peer->close(s->peer);
        s->peer = nullptr;
    }

    remove_socket(s);
    delete s;
}

static int jdwp_socket_enqueue(asocket* s, apacket::payload_type) {
    /* you can't write to this asocket */
    D("LS(%d): JDWP socket received data?", s->id);
    s->peer->close(s->peer);
    return -1;
}

static void jdwp_socket_ready(asocket* s) {
    JdwpSocket* jdwp = (JdwpSocket*)s;
    asocket* peer = jdwp->peer;

    /* on the first call, send the list of pids,
     * on the second one, close the connection
     */
    if (!jdwp->pass) {
        apacket::payload_type data;
        data.resize(s->get_max_payload());
        size_t len = jdwp_process_list(&data[0], data.size());
        data.resize(len);
        peer->enqueue(peer, std::move(data));
        jdwp->pass = true;
    } else {
        peer->close(peer);
    }
}

asocket* create_jdwp_service_socket(void) {
    JdwpSocket* s = new JdwpSocket();

    if (!s) {
        LOG(FATAL) << "failed to allocate JdwpSocket";
    }

    install_local_socket(s);

    s->ready = jdwp_socket_ready;
    s->enqueue = jdwp_socket_enqueue;
    s->close = jdwp_socket_close;
    s->pass = false;

    return s;
}

/** "track-jdwp" local service implementation
 ** this periodically sends the list of known JDWP process pids
 ** to the client...
 **/

struct JdwpTracker : public asocket {
    TrackerKind kind;
    bool need_initial;

    explicit JdwpTracker(TrackerKind k, bool initial) : kind(k), need_initial(initial) {}
};

static auto& _jdwp_trackers = *new std::vector<std::unique_ptr<JdwpTracker>>();

static void process_list_updated(TrackerKind kind) {
    // Find out the max payload we can output.
    // We start with the max the protocol can handle (hex4).
    size_t maxPayload = UINT16_MAX;
    for (auto& t : _jdwp_trackers) {
        maxPayload = std::min(maxPayload, t->get_max_payload());
    }

    std::string data;
    data.resize(maxPayload);
    data.resize(process_list_msg(kind, &data[0], data.size()));

    for (auto& t : _jdwp_trackers) {
        if (t->kind == kind && t->peer) {
            // The tracker might not have been connected yet.
            apacket::payload_type payload(data.begin(), data.end());
            t->peer->enqueue(t->peer, std::move(payload));
        }
    }
}

static void jdwp_process_list_updated(void) {
    process_list_updated(TrackerKind::kJdwp);
}

static void app_process_list_updated(void) {
    process_list_updated(TrackerKind::kApp);
}

static void jdwp_tracker_close(asocket* s) {
    D("LS(%d): destroying jdwp tracker service", s->id);

    if (s->peer) {
        D("LS(%d) peer->close()ing peer->id=%d peer->fd=%d", s->id, s->peer->id, s->peer->fd);
        s->peer->peer = nullptr;
        s->peer->close(s->peer);
        s->peer = nullptr;
    }

    remove_socket(s);

    auto pred = [s](const auto& tracker) { return tracker.get() == s; };
    _jdwp_trackers.erase(std::remove_if(_jdwp_trackers.begin(), _jdwp_trackers.end(), pred),
                         _jdwp_trackers.end());
}

static void jdwp_tracker_ready(asocket* s) {
    JdwpTracker* t = (JdwpTracker*)s;

    if (t->need_initial) {
        apacket::payload_type data;
        data.resize(s->get_max_payload());
        data.resize(process_list_msg(t->kind, &data[0], data.size()));
        t->need_initial = false;
        s->peer->enqueue(s->peer, std::move(data));
    }
}

static int jdwp_tracker_enqueue(asocket* s, apacket::payload_type) {
    /* you can't write to this socket */
    D("LS(%d): JDWP tracker received data?", s->id);
    s->peer->close(s->peer);
    return -1;
}

static asocket* create_process_tracker_service_socket(TrackerKind kind) {
    std::unique_ptr<JdwpTracker> t = std::make_unique<JdwpTracker>(kind, true);
    if (!t) {
        LOG(FATAL) << "failed to allocate JdwpTracker";
    }

    /* Object layout (with an inheritance hierarchy) varies across arch (e.g
     * armv7a/Android TV vs aarch64), so no assumptions can be made about
     * accessing fields based on offsets (e.g memset(t.get(), 0, sizeof(asocket))
     * might clobber an unintended memory location).
     */

    install_local_socket(t.get());
    D("LS(%d): created new jdwp tracker service", t->id);

    t->ready = jdwp_tracker_ready;
    t->enqueue = jdwp_tracker_enqueue;
    t->close = jdwp_tracker_close;

    asocket* result = t.get();

    _jdwp_trackers.emplace_back(std::move(t));

    return result;
}

asocket* create_jdwp_tracker_service_socket() {
    return create_process_tracker_service_socket(TrackerKind::kJdwp);
}

asocket* create_app_tracker_service_socket() {
    return create_process_tracker_service_socket(TrackerKind::kApp);
}

int init_jdwp(void) {
    std::thread([]() {
        adb_thread_setname("jdwp control");
        adbconnection_listen([](int fd, ProcessInfo process) {
            LOG(INFO) << "jdwp connection from " << process.pid;
            fdevent_run_on_looper([fd, process] {
                unique_fd ufd(fd);
                auto proc = std::make_unique<JdwpProcess>(std::move(ufd), process);
                if (!proc) {
                    LOG(FATAL) << "failed to allocate JdwpProcess";
                }
                _jdwp_list.emplace_back(std::move(proc));
                if (process.debuggable) jdwp_process_list_updated();
                if (process.debuggable || process.profileable) app_process_list_updated();
            });
        });
    }).detach();
    return 0;
}

#else  // !defined(__ANDROID_RECOVERY)
#include "adb.h"

asocket* create_jdwp_service_socket(void) {
    return nullptr;
}

unique_fd create_jdwp_connection_fd(int pid) {
    return {};
}

asocket* create_app_tracker_service_socket() {
    return nullptr;
}

asocket* create_jdwp_tracker_service_socket() {
    return nullptr;
}

int init_jdwp() {
    return 0;
}

#endif /* defined(__ANDROID_RECOVERY__) */
