/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 "core/conf.h"
#include "core/htrace.h"
#include "test/mini_htraced.h"
#include "test/temp_dir.h"
#include "test/test_config.h"
#include "test/test.h"
#include "util/log.h"

#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <json/json_object.h>
#include <json/json_tokener.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

/**
 * The maximum size of the notification data sent from the htraced daemon on
 * startup.
 */
#define MAX_NDATA 65536

/**
 * The separator to use in between paths.  TODO: portability
 */
#define PATH_LIST_SEP ':'

/**
 * The maximum number of arguments when launching an external process.
 */
#define MAX_LAUNCH_ARGS 32

/**
 * Retry an operation that may get EINTR.
 * The operation must return a non-negative value on success.
 */
#define RETRY_ON_EINTR(ret, expr) do { \
    ret = expr; \
    if (ret >= 0) \
        break; \
} while (errno == EINTR);

#define MINI_HTRACED_LAUNCH_REDIRECT_FDS 0x1

static void mini_htraced_open_snsock(struct mini_htraced *ht, char *err,
                                     size_t err_len);

static void mini_htraced_write_conf_file(struct mini_htraced *ht,
                                  char *err, size_t err_len);

static int mini_htraced_write_conf_key(FILE *fp, const char *key,
                                       const char *fmt, ...)
    __attribute__((format(printf, 3, 4)));

static void mini_htraced_launch_daemon(struct mini_htraced *ht,
                                char *err, size_t err_len);

/**
 * Launch an external process.
 *
 * @param ht                The mini htraced object.
 * @param path              The binary to launch
 * @param err               (out param) the error, or empty string on success.
 * @param err_len           The length of the error buffer.
 * @param flags             The flags.
 *                              MINI_HTRACED_LAUNCH_REDIRECT_FDS: redirect
 *                                  stderr, stdout, stdin to null.
 *                                  finished successfully.
 * @param ...               Additional arguments to pass to the process.
 *                              NULL_terminated.  The first argument will
 *                              always be the path to the binary.
 *
 * @return                  The new process ID, on success.  -1 on failure.
 *                              The error string will always be set on failure.
 */
pid_t mini_htraced_launch(const struct mini_htraced *ht, const char *path,
                         char *err, size_t err_len, int flags, ...)
    __attribute__((sentinel));


static void mini_htraced_read_startup_notification(struct mini_htraced *ht,
                                       char *err, size_t err_len);

static void parse_startup_notification(struct mini_htraced *ht,
                                       char *ndata, size_t ndata_len,
                                       char *err, size_t err_len);

void mini_htraced_build(const struct mini_htraced_params *params,
                        struct mini_htraced **hret,
                        char *err, size_t err_len)
{
    struct mini_htraced *ht = NULL;
    int i, ret;

    err[0] = '\0';
    ht = calloc(1, sizeof(*ht));
    if (!ht) {
        snprintf(err, err_len, "out of memory allocating mini_htraced object");
        goto done;
    }
    ht->snsock = -1;
    ht->root_dir = create_tempdir(params->name, 0777, err, err_len);
    if (err[0]) {
        goto done;
    }
    ret = register_tempdir_for_cleanup(ht->root_dir);
    if (ret) {
        snprintf(err, err_len, "register_tempdir_for_cleanup(%s) "
                 "failed: %s", ht->root_dir, terror(ret));
        goto done;
    }
    for (i = 0; i < NUM_DATA_DIRS; i++) {
        if (asprintf(ht->data_dir + i, "%s/dir%d", ht->root_dir, i) < 0) {
            ht->data_dir[i] = NULL;
            snprintf(err, err_len, "failed to create path to data dir %d", i);
            goto done;
        }
    }
    if (asprintf(&ht->htraced_log_path, "%s/htraced.log", ht->root_dir) < 0) {
        ht->htraced_log_path = NULL;
        snprintf(err, err_len, "failed to create path to htraced.log");
        goto done;
    }
    if (asprintf(&ht->htraced_conf_path, "%s/htraced-conf.xml",
                 ht->root_dir) < 0) {
        ht->htraced_conf_path = NULL;
        snprintf(err, err_len, "failed to create path to htraced-conf.xml");
        goto done;
    }
    mini_htraced_open_snsock(ht, err, err_len);
    if (err[0]) {
        goto done;
    }
    mini_htraced_write_conf_file(ht, err, err_len);
    if (err[0]) {
        goto done;
    }
    mini_htraced_launch_daemon(ht, err, err_len);
    if (err[0]) {
        goto done;
    }
    mini_htraced_read_startup_notification(ht, err, err_len);
    if (err[0]) {
        goto done;
    }
    if (asprintf(&ht->client_conf_defaults, "%s=%s",
             HTRACED_ADDRESS_KEY, ht->htraced_http_addr) < 0) {
        ht->client_conf_defaults = NULL;
        snprintf(err, err_len, "failed to allocate client conf defaults.");
        goto done;
    }
    *hret = ht;
    err[0] = '\0';

done:
    if (err[0]) {
        mini_htraced_free(ht);
    }
}

static int do_waitpid(pid_t pid, char *err, size_t err_len)
{
    err[0] = '\0';
    while (1) {
        int status, res = waitpid(pid, &status, 0);
        if (res < 0) {
            if (errno == EINTR) {
                continue;
            }
            snprintf(err, err_len, "waitpid(%lld) error: %s",
                    (long long)pid, terror(res));
            return -1;
        }
        if (WIFEXITED(status)) {
            return WEXITSTATUS(status);
        }
        return -1; // signal or other exit
    }
}

void mini_htraced_stop(struct mini_htraced *ht)
{
    char err[512];
    size_t err_len = sizeof(err);

    if (!ht->htraced_pid_valid) {
        return;
    }
    kill(ht->htraced_pid, SIGTERM);
    ht->htraced_pid_valid = 0;
    do_waitpid(ht->htraced_pid, err, err_len);
    if (err[0]) {
        fprintf(stderr, "%s\n", err);
    }
}

void mini_htraced_free(struct mini_htraced *ht)
{
    int i;

    if (!ht) {
        return;
    }
    mini_htraced_stop(ht);
    if (ht->root_dir) {
        unregister_tempdir_for_cleanup(ht->root_dir);
        if (!getenv("SKIP_CLEANUP")) {
            recursive_unlink(ht->root_dir);
        }
    }
    free(ht->root_dir);
    for (i = 0; i < NUM_DATA_DIRS; i++) {
        free(ht->data_dir[i]);
    }
    free(ht->htraced_log_path);
    free(ht->htraced_conf_path);
    free(ht->client_conf_defaults);
    if (ht->snsock >= 0) {
        close(ht->snsock);
        ht->snsock = -1;
    }
    free(ht->htraced_http_addr);
    free(ht);
}

static void mini_htraced_open_snsock(struct mini_htraced *ht, char *err,
                                     size_t err_len)
{
    struct sockaddr_in snaddr;
    socklen_t len = sizeof(snaddr);
    struct timeval tv;

    err[0] = '\0';
    memset(&snaddr, 0, sizeof(snaddr));
    snaddr.sin_family = AF_INET;
    snaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    ht->snsock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (ht->snsock < 0) {
        int res = errno;
        snprintf(err, err_len, "Failed to create new socket: %s\n",
                 terror(res));
        return;
    }
    if (bind(ht->snsock, (struct sockaddr *) &snaddr, sizeof(snaddr)) < 0) {
        int res = errno;
        snprintf(err, err_len, "bind failed: %s\n", terror(res));
        return;
    }
    if (getsockname(ht->snsock, (struct sockaddr *)&snaddr, &len) < 0) {
        int res = errno;
        snprintf(err, err_len, "getsockname failed: %s\n", terror(res));
        return;
    }
    ht->snport = ntohs(snaddr.sin_port);
    if (listen(ht->snsock, 32) < 0) {
        int res = errno;
        snprintf(err, err_len, "listen failed: %s\n", terror(res));
        return;
    }
    // On Linux, at least, this makes accept() time out after 30 seconds.  I'm
    // too lazy to use select() here.
    tv.tv_sec = 30;
    tv.tv_usec = 0;
    setsockopt(ht->snsock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
}

static void mini_htraced_write_conf_file(struct mini_htraced *ht,
                                  char *err, size_t err_len)
{
    FILE *fp;
    int res;

    err[0] = '\0';
    fp = fopen(ht->htraced_conf_path, "w");
    if (!fp) {
        res = errno;
        snprintf(err, err_len, "fopen(%s) failed: %s",
                 ht->htraced_conf_path, terror(res));
        goto error;
    }
    if (fprintf(fp, "\
<?xml version=\"1.0\"?>\n\
<?xml-stylesheet type=\"text/xsl\" href=\"configuration.xsl\"?>\n\
<configuration>\n") < 0) {
        goto ioerror;
    }
    if (mini_htraced_write_conf_key(fp, "log.path", "%s",
                                    ht->htraced_log_path)) {
        goto ioerror;
    }
    if (mini_htraced_write_conf_key(fp, "web.address", "127.0.0.1:0")) {
        goto ioerror;
    }
    if (mini_htraced_write_conf_key(fp, "data.store.directories",
            "%s%c%s", ht->data_dir[0], PATH_LIST_SEP, ht->data_dir[1])) {
        goto ioerror;
    }
    if (mini_htraced_write_conf_key(fp, "startup.notification.address",
            "localhost:%d", ht->snport)) {
        goto ioerror;
    }
    if (mini_htraced_write_conf_key(fp, "log.level", "%s", "TRACE")) {
        goto ioerror;
    }
    if (fprintf(fp, "</configuration>\n") < 0) {
        goto ioerror;
    }
    res = fclose(fp);
    if (res) {
        snprintf(err, err_len, "fclose(%s) failed: %s",
                 ht->htraced_conf_path, terror(res));
    }
    return;

ioerror:
    snprintf(err, err_len, "fprintf(%s) error",
             ht->htraced_conf_path);
error:
    if (fp) {
        fclose(fp);
    }
}

static int mini_htraced_write_conf_key(FILE *fp, const char *key,
                                       const char *fmt, ...)
{
    va_list ap;

    if (fprintf(fp, "  <property>\n    <name>%s</name>\n    <value>",
                key) < 0) {
        return 1;
    }
    va_start(ap, fmt);
    if (vfprintf(fp, fmt, ap) < 0) {
        va_end(ap);
        return 1;
    }
    va_end(ap);
    if (fprintf(fp, "</value>\n  </property>\n") < 0) {
        return 1;
    }
    return 0;
}

pid_t mini_htraced_launch(const struct mini_htraced *ht, const char *path,
                         char *err, size_t err_len, int flags, ...)
{
    pid_t pid;
    int res, num_args = 0;
    va_list ap;
    const char *args[MAX_LAUNCH_ARGS + 1];
    const char * const env[] = {
        "HTRACED_CONF_DIR=.", "HTRACED_WEB_DIR=", NULL
    };

    err[0] = '\0';
    if (access(path, X_OK) < 0) {
        snprintf(err, err_len, "The %s binary is not accessible and "
                 "executable.", path);
        return -1;
    }
    va_start(ap, flags);
    args[num_args++] = path;
    while (1) {
        const char *arg = va_arg(ap, char*);
        if (!arg) {
            break;
        }
        if (num_args >= MAX_LAUNCH_ARGS) {
            va_end(ap);
            snprintf(err, err_len, "Too many arguments to launch!  The "
                 "maximum number of arguments is %d.\n", MAX_LAUNCH_ARGS);
            return -1;
        }
        args[num_args++] = arg;
    }
    va_end(ap);
    args[num_args++] = NULL;

    pid = fork();
    if (pid == -1) {
        // Fork failed.
        res = errno;
        snprintf(err, err_len, "fork() failed for %s: %s\n",
                 path, terror(res));
        return -1;
    } else if (pid == 0) {
        // Child process.
        // We don't want to delete the temporary directory when this child
        // process exists.  The parent process is responsible for that, if it
        // is to be done at all.
        unregister_tempdir_for_cleanup(ht->root_dir);

        // Make things nicer by exiting when the parent process exits.
        prctl(PR_SET_PDEATHSIG, SIGHUP);

        if (flags & MINI_HTRACED_LAUNCH_REDIRECT_FDS) {
            int null_fd;
            RETRY_ON_EINTR(null_fd, open("/dev/null", O_WRONLY));
            if (null_fd < 0) {
                _exit(127);
            }
            RETRY_ON_EINTR(res, dup2(null_fd, STDOUT_FILENO));
            if (res < 0) {
                _exit(127);
            }
            RETRY_ON_EINTR(res, dup2(null_fd, STDERR_FILENO));
            if (res < 0) {
                _exit(127);
            }
        }
        if (chdir(ht->root_dir) < 0) {
            _exit(127);
        }
        execve(path, (char *const*)args, (char * const*)env);
        _exit(127);
    }
    // Parent process.
    return pid;
}

static void mini_htraced_launch_daemon(struct mini_htraced *ht,
                                char *err, size_t err_len)
{
    int flags = 0;
    pid_t pid;

    if (!getenv("SKIP_CLEANUP")) {
        flags |= MINI_HTRACED_LAUNCH_REDIRECT_FDS;
    }
    pid = mini_htraced_launch(ht, HTRACED_ABSPATH, err, err_len, flags, NULL);
    if (err[0]) {
        return;
    }
    ht->htraced_pid_valid = 1;
    ht->htraced_pid = pid;
}

void mini_htraced_dump_spans(struct mini_htraced *ht,
                             char *err, size_t err_len,
                             const char *path)
{
    pid_t pid;
    int ret;
    char *addr = NULL;

    err[0] = '\0';
    if (asprintf(&addr, "--addr=%s", ht->htraced_http_addr) < 0) {
        addr = NULL;
        snprintf(err, err_len, "OOM while allocating the addr string");
        return;
    }
    pid = mini_htraced_launch(ht, HTRACE_ABSPATH, err, err_len, 0,
                addr, "dumpAll", path, NULL);
    free(addr);
    if (err[0]) {
        return;
    }
    ret = do_waitpid(pid, err, err_len);
    if (err[0]) {
        return;
    }
    if (ret != EXIT_SUCCESS) {
        snprintf(err, err_len, "%s returned non-zero exit status %d\n",
                 HTRACE_ABSPATH, ret);
        return;
    }
}

static void mini_htraced_read_startup_notification(struct mini_htraced *ht,
                                       char *err, size_t err_len)
{
    char *ndata = NULL;
    int res, sock = -1;
    size_t ndata_len = 0;

    err[0] = '\0';
    ndata = malloc(MAX_NDATA);
    if (!ndata) {
        snprintf(err, err_len, "failed to allocate %d byte buffer for "
                 "notification data.", MAX_NDATA);
        goto done;
    }
    RETRY_ON_EINTR(sock, accept(ht->snsock, NULL, NULL));
    if (sock < 0) {
        int e = errno;
        snprintf(err, err_len, "accept failed: %s", terror(e));
        goto done;
    }
    while (ndata_len < MAX_NDATA) {
        res = recv(sock, ndata + ndata_len, MAX_NDATA - ndata_len, 0);
        if (res == 0) {
            break;
        }
        if (res < 0) {
            int e = errno;
            if (e == EINTR) {
                continue;
            }
            snprintf(err, err_len, "recv error: %s", terror(e));
            goto done;
        }
        ndata_len += res;
    }
    parse_startup_notification(ht, ndata, ndata_len, err, err_len);
    if (err[0]) {
        goto done;
    }

done:
    if (sock >= 0) {
        close(sock);
    }
    free(ndata);
}

static void parse_startup_notification(struct mini_htraced *ht,
                                       char *ndata, size_t ndata_len,
                                       char *err, size_t err_len)
{
    struct json_tokener *tok = NULL;
    struct json_object *root = NULL, *http_addr, *process_id;
    int32_t pid;

    err[0] = '\0';
    tok = json_tokener_new();
    if (!tok) {
        snprintf(err, err_len, "json_tokener_new failed.");
        goto done;
    }
    root = json_tokener_parse_ex(tok, ndata, ndata_len);
    if (!root) {
        enum json_tokener_error jerr = json_tokener_get_error(tok);
        snprintf(err, err_len, "Failed to parse startup notification: %s.",
                 json_tokener_error_desc(jerr));
        goto done;
    }
    // Find the http address, in the form of hostname:port, which the htraced
    // is listening on.
    if (!json_object_object_get_ex(root, "HttpAddr", &http_addr)) {
        snprintf(err, err_len, "Failed to find HttpAddr in the startup "
                 "notification.");
        goto done;
    }
    ht->htraced_http_addr = strdup(json_object_get_string(http_addr));
    if (!ht->htraced_http_addr) {
        snprintf(err, err_len, "OOM");
        goto done;
    }
    // Check that the process ID from the startup notification matches the
    // process ID from the fork.
    if (!json_object_object_get_ex(root, "ProcessId", &process_id)) {
        snprintf(err, err_len, "Failed to find ProcessId in the startup "
                 "notification.");
        goto done;
    }
    pid = json_object_get_int(process_id);
    if (pid != ht->htraced_pid) {
        snprintf(err, err_len, "Startup notification pid was %lld, but the "
                 "htraced process id was %lld.",
                 (long long)pid, (long long)ht->htraced_pid);
        goto done;
    }

done:
    json_tokener_free(tok);
    if (root) {
        json_object_put(root);
    }
}

// vim: ts=4:sw=4:tw=79:et
