/*
 *  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 <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <ctype.h>

#include "port_dso.h"
#include "port_malloc.h"
#include "stack_dump.h"

#if defined(MACOSX)
#include <crt_externs.h>
#define environ (*_NSGetEnviron())
#else
extern char** environ;
#endif

static char* g_curdir = NULL;
static char* g_cmdline = NULL;


static inline native_segment_t* sd_find_segment(native_module_t* module, void* ip)
{
    for (size_t i = 0; i < module->seg_count; i++)
    {
        if (module->segments[i].base <= ip &&
            (char*)module->segments[i].base + module->segments[i].size > ip)
            return &module->segments[i];
    }

    assert(0);
    return NULL;
}

void sd_get_c_method_info(CFunInfo* info, native_module_t* module, void* ip)
{
    *info->name = '\0';
    *info->filename = '\0';
    info->line = -1;

    if (!module || !module->filename)
        return;

    POINTER_SIZE_INT offset = (POINTER_SIZE_INT)ip;

    if (strstr(module->filename, PORT_DSO_EXT) != NULL) // Shared object
    { // IP for addr2line should be an offset within shared library
        native_segment_t* seg = sd_find_segment(module, ip);
        offset -= (POINTER_SIZE_INT)seg->base;
    }

    int po[2];
    pipe(po);

    char ip_str[20];
    sprintf(ip_str, "0x%"PI_FMT"x\n", offset);

    if (!fork())
    {
        close(po[0]);
        dup2(po[1], 1);
        execlp("addr2line", "addr2line", "-f", "-s", "-e", module->filename, "-C", ip_str, NULL);
        //fprintf(stderr, "Warning: Cannot run addr2line. No symbolic information will be available\n");
        printf("??\n??:0\n"); // Emulate addr2line output
        exit(-1);
    }
    else
    {
        close(po[1]);
        char buf[sizeof(info->name) + sizeof(info->filename)];
        int status;
        wait(&status);
        int count = read(po[0], buf, sizeof(buf) - 1);
        close(po[0]);

        if (count < 0)
        {
            fprintf(stderr, "read() failed during addr2line execution\n");
            return;
        }

        while (isspace(buf[count-1]))
            count--;

        buf[count] = '\0';
        int i = 0;

        for (; i < count; i++)
        {
            if (buf[i] == '\n')
            { // Function name is limited by '\n'
                buf[i] = '\0';
                strncpy(info->name, buf, sizeof(info->name));
                break;
            }
        }

        if (i == count)
            return;

        char* fn = buf + i + 1;

        for (; i < count && buf[i] != ':'; i++); // File name and line number are separated by ':'

        if (i == count)
            return;

        buf[i] = '\0';
        strncpy(info->filename, fn, sizeof(info->filename));

        info->line = atoi(buf + i + 1); // Line number

        if (info->line == 0)
            info->line = -1;
    }
}

void sd_init_crash_handler()
{
    // Get current directory
    char buf[PATH_MAX + 1];
    char* cwd = getcwd(buf, sizeof(buf));

    if (cwd)
    {
        cwd = (char*)STD_MALLOC(strlen(cwd) + 1);
        g_curdir = cwd;
        if (cwd)
            strcpy(cwd, buf);
    }

    // Get command line
    sprintf(buf, "/proc/%d/cmdline", getpid());
    int file = open(buf, O_RDONLY);

    if (file > 0)
    {
        size_t size = 0;
        char rdbuf[256];
        ssize_t rd;
        do
        {
            rd = read(file, rdbuf, sizeof(rdbuf));
            size += (rd > 0) ? rd : 0;
        } while (rd == sizeof(rdbuf));

        if (size)
        {
            char* cmd = (char*)STD_MALLOC(size + 1);
            g_cmdline = cmd;
            if (cmd)
            {
                cmd[size] = '\0';
                lseek(file, 0, SEEK_SET);
                read(file, cmd, size);
            }
        }
        close(file);
    }
}

void sd_cleanup_crash_handler()
{
    if (g_curdir)
        STD_FREE(g_curdir);
    if (g_cmdline)
        STD_FREE(g_cmdline);
}

void sd_print_cmdline_cwd()
{
    fprintf(stderr, "\nCommand line:\n");

    if (g_cmdline)
    {
        for (const char* ptr = g_cmdline; *ptr; ptr += strlen(ptr) + 1)
            fprintf(stderr, "%s ", ptr);
        fprintf(stderr, "\n");
    }
    else
        fprintf(stderr, "is unavailable, probably /proc is not mounted\n");

    fprintf(stderr, "\nWorking directory:\n%s\n", g_curdir ? g_curdir : "'null'");
}

void sd_print_environment()
{
    fprintf(stderr, "\nEnvironment variables:\n");
    for (char** env = environ; *env; ++env)
        fprintf(stderr, "%s\n", *env);
}
