// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <runtests-utils/fuchsia-run-test.h>

#include <errno.h>
#include <fcntl.h>
#include <libgen.h>
#include <stdio.h>
#include <sys/stat.h>
#include <unistd.h>

#include <fbl/auto_call.h>
#include <fbl/string.h>
#include <fbl/string_printf.h>
#include <fbl/unique_fd.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/io.h>
#include <lib/fdio/spawn.h>
#include <lib/zx/job.h>
#include <lib/zx/process.h>
#include <loader-service/loader-service.h>
#include <zircon/dlfcn.h>
#include <zircon/process.h>
#include <zircon/processargs.h>
#include <zircon/status.h>
#include <zircon/syscalls.h>

#include <utility>

namespace runtests {

// Path to helper binary which can run test as a component. This binary takes
// component url as its parameter.
constexpr char kRunTestComponentPath[] = "/bin/run-test-component";

fbl::String DirectoryName(const fbl::String& path) {
    char* cpath = strndup(path.data(), path.length());
    fbl::String ret(dirname(cpath));
    free(cpath);
    return ret;
}

fbl::String BaseName(const fbl::String& path) {
    char* cpath = strndup(path.data(), path.length());
    fbl::String ret(basename(cpath));
    free(cpath);
    return ret;
}

void TestFileComponentInfo(const fbl::String path,
                           fbl::String* component_url_out,
                           fbl::String* cmx_file_path_out) {
    if (strncmp(path.c_str(), kPkgPrefix, strlen(kPkgPrefix)) != 0) {
        return;
    }

    // Consume suffixes of the form
    // "test/<test filename>" or "test/disabled/<test filename>"
    bool is_disabled = (strstr(path.c_str(), "/disabled/") != nullptr);
    const auto folder_path = is_disabled?
                             DirectoryName(DirectoryName(DirectoryName(path))):
                             DirectoryName(DirectoryName(path));

    // folder_path should also start with |kPkgPrefix| and should not be equal
    // to |kPkgPrefix|.
    if (strncmp(folder_path.c_str(), kPkgPrefix, strlen(kPkgPrefix)) != 0 ||
        folder_path == fbl::String(kPkgPrefix)) {
        return;
    }

    const char* package_name = path.c_str() + strlen(kPkgPrefix);
    // find occurence of first '/'
    size_t i = 0;
    while (package_name[i] != '\0' && package_name[i] != '/') {
        i++;
    }
    const fbl::String package_name_str(package_name, i);
    const auto test_file_name = BaseName(path);
    *cmx_file_path_out = fbl::StringPrintf(
        "%s/meta/%s.cmx", folder_path.c_str(), test_file_name.c_str());
    *component_url_out =
        fbl::StringPrintf("fuchsia-pkg://fuchsia.com/%s#meta/%s.cmx",
                          package_name_str.c_str(), test_file_name.c_str());
}

namespace {

struct DataSinkDump {
    fbl::String sink_name;
    zx::vmo file_data;
};

struct LoaderServiceState {
    fbl::unique_fd root_dir_fd;
    fbl::Vector<DataSinkDump> data;
};

// This is a default set of library paths.
//
// Unfortunately this is duplicated in loader-service. We could get rid of this duplication by
// delegating to the existing loader service over FIDL for everything except PublishDataSink(),
// but the added complexity doesn't seem worth it.
const char* const kLibPaths[] = {"system/lib", "boot/lib"};

// This is a helper specifically for the C API boundary with the implementation code.
zx_status_t ExecVmoFromFd(fbl::unique_fd fd, const char* file_name, zx_handle_t* out) {
    zx_handle_t vmo;
    zx_handle_t exec_vmo;

    zx_status_t status = fdio_get_vmo_clone(fd.get(), &vmo);
    if (status != ZX_OK) {
        return status;
    }

    status = zx_vmo_replace_as_executable(vmo, ZX_HANDLE_INVALID, &exec_vmo);
    if (status != ZX_OK) {
        zx_handle_close(vmo);
        return status;
    }

    status = zx_object_set_property(exec_vmo, ZX_PROP_NAME, file_name, strlen(file_name));
    if (status != ZX_OK) {
        zx_handle_close(exec_vmo);
        return status;
    }

    *out = exec_vmo;
    return ZX_OK;
}

zx_status_t LoadObject(void* ctx, const char* name, zx_handle_t* out) {
    const auto state = static_cast<LoaderServiceState*>(ctx);
    for (const auto libdir : kLibPaths) {
        char path[PATH_MAX];
        if (snprintf(path, sizeof(path), "%s/%s", libdir, name) < 0) {
            return ZX_ERR_INTERNAL;
        }
        fbl::unique_fd fd(openat(state->root_dir_fd.get(), path, O_RDONLY));
        if (fd) {
            return ExecVmoFromFd(std::move(fd), name, out);
        }
    }
    return ZX_ERR_NOT_FOUND;
}

zx_status_t LoadAbspath(void* ctx, const char* path, zx_handle_t* out) {
    const auto state = static_cast<LoaderServiceState*>(ctx);
    fbl::unique_fd fd(openat(state->root_dir_fd.get(), path, O_RDONLY));
    if (fd) {
        return ExecVmoFromFd(std::move(fd), path, out);
    }
    return ZX_ERR_NOT_FOUND;
}

zx_status_t PublishDataSink(void* ctx, const char* sink_name, zx_handle_t vmo) {
    const auto state = static_cast<LoaderServiceState*>(ctx);
    state->data.push_back({ sink_name, zx::vmo{vmo} });
    return ZX_OK;
}

void Finalizer(void* ctx) {
    const auto state = static_cast<LoaderServiceState*>(ctx);
    delete state;
}

const loader_service_ops_t fd_ops = {
    .load_object = LoadObject,
    .load_abspath = LoadAbspath,
    .publish_data_sink = PublishDataSink,
    .finalizer = Finalizer,
};

// To avoid creating a separate service thread for each test, we have a global
// instance of the async loop which is shared by all tests and their loader services.
std::unique_ptr<async::Loop> loop;

} // namespace

std::unique_ptr<Result> FuchsiaRunTest(const char* argv[],
                                       const char* output_dir,
                                       const char* output_filename) {
    // The arguments passed to fdio_spaws_etc. May be overridden.
    const char** args = argv;
    // calculate size of argv
    size_t argc = 0;
    while (argv[argc] != nullptr) {
        argc++;
    }

    // Values used when running the test as a component.
    const char* component_launch_args[argc + 2];
    fbl::String component_url;
    fbl::String cmx_file_path;

    const char* path = argv[0];

    TestFileComponentInfo(path, &component_url, &cmx_file_path);
    struct stat s;
    // If we get a non empty |cmx_file_path|, check that it exists, and if
    // present launch the test as component using generated |component_url|.
    if (cmx_file_path != "" && stat(cmx_file_path.c_str(), &s) == 0) {
        if (stat(kRunTestComponentPath, &s) == 0) {
            component_launch_args[0] = kRunTestComponentPath;
            component_launch_args[1] = component_url.c_str();
            for (size_t i = 1; i <= argc; i++) {
                component_launch_args[1 + i] = argv[i];
            }
            args = component_launch_args;
        } else {
            // TODO(anmittal): Make this a error once we have a stable
            // system and we can run all tests as components.
            fprintf(stderr,
                    "WARNING: Cannot find '%s', running '%s' as normal test "
                    "binary.",
                    kRunTestComponentPath, path);
        }
    }

    fbl::Vector<fdio_spawn_action_t> fdio_actions = {
        fdio_spawn_action_t{.action = FDIO_SPAWN_ACTION_SET_NAME,
          .name = {.data = path}},
    };

    LoaderServiceState* state = nullptr;
    zx_handle_t svc_handle = ZX_HANDLE_INVALID;
    loader_service_t* loader_service = nullptr;
    auto release_service = fbl::MakeAutoCall([&]() {
        if (loader_service != nullptr) {
            loader_service_release(loader_service);
        }
    });

    if (output_dir != nullptr) {
        state = new LoaderServiceState();
        // If |output_dir| is provided, set up the loader service that will be
        // used to capture any data published.
        state->root_dir_fd.reset(open("/", O_RDONLY | O_DIRECTORY));
        if (!state->root_dir_fd) {
            printf("FAILURE: Could not open root directory /\n");
            return std::make_unique<Result>(path, FAILED_UNKNOWN, 0);
        }

        if (!loop) {
            loop.reset(new async::Loop(&kAsyncLoopConfigNoAttachToThread));
            if (loop->StartThread("loader-service") != ZX_OK) {
                printf("FAILURE: cannot start message loop\n");
                loop.reset();
                return std::make_unique<Result>(path, FAILED_UNKNOWN, 0);
            }
        }

        if (loader_service_create(loop->dispatcher(), &fd_ops, state, &loader_service) != ZX_OK) {
            printf("FAILURE: cannot create loader service\n");
            delete state;
            return std::make_unique<Result>(path, FAILED_UNKNOWN, 0);
        }

        if (loader_service_connect(loader_service, &svc_handle) != ZX_OK) {
            printf("FAILURE: cannot connect loader service\n");
            return std::make_unique<Result>(path, FAILED_UNKNOWN, 0);
        }

        fdio_actions.push_back(
            fdio_spawn_action{.action = FDIO_SPAWN_ACTION_ADD_HANDLE,
             .h = {.id = PA_LDSVC_LOADER, .handle = svc_handle}});
    }

    // If |output_filename| is provided, prepare the file descriptors that will
    // be used to tee the stdout/stderr of the test into the associated file.
    fbl::unique_fd fds[2];
    if (output_filename != nullptr) {
        int temp_fds[2] = {-1, -1};
        if (pipe(temp_fds)) {
            fprintf(stderr, "FAILURE: Failed to create pipe: %s\n",
                    strerror(errno));
            return std::make_unique<Result>(path, FAILED_TO_LAUNCH, 0);
        }
        fds[0].reset(temp_fds[0]);
        fds[1].reset(temp_fds[1]);

        fdio_actions.push_back(
            fdio_spawn_action{.action = FDIO_SPAWN_ACTION_CLONE_FD,
             .fd = {.local_fd = fds[1].get(), .target_fd = STDOUT_FILENO}});
        fdio_actions.push_back(
            fdio_spawn_action{.action = FDIO_SPAWN_ACTION_TRANSFER_FD,
             .fd = {.local_fd = fds[1].get(), .target_fd = STDERR_FILENO}});
    }
    zx_status_t status = ZX_OK;
    zx::job test_job;
    status = zx::job::create(*zx::job::default_job(), 0, &test_job);
    if (status != ZX_OK) {
        fprintf(stderr, "FAILURE: zx::job::create() returned %d\n", status);
        return std::make_unique<Result>(path, FAILED_TO_LAUNCH, 0);
    }
    auto auto_call_kill_job =
        fbl::MakeAutoCall([&test_job]() { test_job.kill(); });
    status =
        test_job.set_property(ZX_PROP_NAME, "run-test", sizeof("run-test"));
    if (status != ZX_OK) {
        fprintf(stderr, "FAILURE: set_property() returned %d\n", status);
        return std::make_unique<Result>(path, FAILED_TO_LAUNCH, 0);
    }

    fds[1].release(); // To avoid double close since fdio_spawn_etc() closes it.
    zx::process process;
    char err_msg[FDIO_SPAWN_ERR_MSG_MAX_LENGTH];
    status = fdio_spawn_etc(test_job.get(), FDIO_SPAWN_CLONE_ALL,
                            args[0], args, nullptr,
                            fdio_actions.size(), fdio_actions.get(),
                            process.reset_and_get_address(), err_msg);
    if (status != ZX_OK) {
        fprintf(stderr, "FAILURE: Failed to launch %s: %d (%s): %s\n", path,
                status, zx_status_get_string(status), err_msg);
        return std::make_unique<Result>(path, FAILED_TO_LAUNCH, 0);
    }
    // Tee output.
    if (output_filename != nullptr) {
        FILE* output_file = fopen(output_filename, "w");
        if (output_file == nullptr) {
            fprintf(stderr, "FAILURE: Could not open output file at %s: %s\n",
                    output_filename, strerror(errno));
            return std::make_unique<Result>(path, FAILED_DURING_IO, 0);
        }
        char buf[1024];
        ssize_t bytes_read = 0;
        while ((bytes_read = read(fds[0].get(), buf, sizeof(buf))) > 0) {
            fwrite(buf, 1, bytes_read, output_file);
            fwrite(buf, 1, bytes_read, stdout);
        }
        fflush(stdout);
        fflush(stderr);
        fflush(output_file);
        if (fclose(output_file)) {
            fprintf(stderr, "FAILURE:  Could not close %s: %s", output_filename,
                    strerror(errno));
            return std::make_unique<Result>(path, FAILED_DURING_IO, 0);
        }
    }
    status =
        process.wait_one(ZX_PROCESS_TERMINATED, zx::time::infinite(), nullptr);
    if (status != ZX_OK) {
        fprintf(stderr, "FAILURE: Failed to wait for process exiting %s: %d\n",
                path, status);
        return std::make_unique<Result>(path, FAILED_TO_WAIT, 0);
    }

    // Read the return code.
    zx_info_process_t proc_info;
    status = process.get_info(ZX_INFO_PROCESS, &proc_info, sizeof(proc_info),
                              nullptr, nullptr);

    if (status != ZX_OK) {
        fprintf(stderr, "FAILURE: Failed to get process return code %s: %d\n",
                path, status);
        return std::make_unique<Result>(path, FAILED_TO_RETURN_CODE, 0);
    }

    std::unique_ptr<Result> result;
    if (proc_info.return_code == 0) {
        fprintf(stderr, "PASSED: %s passed\n", path);
        result = std::make_unique<Result>(path, SUCCESS, 0);
    } else {
        fprintf(stderr, "FAILURE: %s exited with nonzero status: %" PRId64 "\n",
                path, proc_info.return_code);
        result = std::make_unique<Result>(path, FAILED_NONZERO_RETURN_CODE,
                                          proc_info.return_code);
    }

    if (output_dir == nullptr) {
        return result;
    }

    // Make sure that all job processes are dead before touching any data.
    auto_call_kill_job.call();

    fbl::unique_fd data_sink_dir_fd{open(output_dir, O_RDONLY | O_DIRECTORY)};
    if (!data_sink_dir_fd) {
        printf("FAILURE: Could not open output directory %s: %s\n", output_dir,
               strerror(errno));
        return result;
    }

    for (auto& data : state->data) {
        if (mkdirat(data_sink_dir_fd.get(), data.sink_name.c_str(), 0777) != 0 && errno != EEXIST) {
            fprintf(stderr, "FAILURE: cannot mkdir \"%s\" for data-sink: %s\n",
                    data.sink_name.c_str(), strerror(errno));
            if (result->return_code == 0) {
                result->launch_status = FAILED_COLLECTING_SINK_DATA;
            }
            continue;
        }
        fbl::unique_fd sink_dir_fd{openat(data_sink_dir_fd.get(), data.sink_name.c_str(),
                                          O_RDONLY | O_DIRECTORY)};
        if (!sink_dir_fd) {
            fprintf(stderr, "FAILURE: cannot open data-sink directory \"%s\": %s\n",
                    data.sink_name.c_str(), strerror(errno));
            if (result->return_code == 0) {
                result->launch_status = FAILED_COLLECTING_SINK_DATA;
            }
            continue;
        }

        uint64_t size;
        zx_status_t status = data.file_data.get_size(&size);
        if (status != ZX_OK) {
            fprintf(stderr, "FAILURE: Cannot get VMO size for data-sink \"%s\": %s\n",
                    data.sink_name.c_str(), zx_status_get_string(status));
            result->launch_status = FAILED_COLLECTING_SINK_DATA;
            continue;
        }

        uintptr_t mapping;
        status = zx::vmar::root_self()->map(0, data.file_data, 0, size,
                                            ZX_VM_PERM_READ, &mapping);
        if (status != ZX_OK) {
            fprintf(stderr, "FAILURE: Cannot map VMO of %" PRIu64 " for data-sink \"%s\": %s\n",
                    size, data.sink_name.c_str(), zx_status_get_string(status));
            if (result->return_code == 0) {
                result->launch_status = FAILED_COLLECTING_SINK_DATA;
            }
            continue;
        }
        auto unmap_vmar = fbl::MakeAutoCall([&]() { zx::vmar::root_self()->unmap(mapping, size); });

        zx_info_handle_basic_t info;
        status = data.file_data.get_info(ZX_INFO_HANDLE_BASIC, &info, sizeof(info),
                                         nullptr, nullptr);
        if (status != ZX_OK) {
            if (result->return_code == 0) {
                result->launch_status = FAILED_COLLECTING_SINK_DATA;
            }
            continue;
        }
        char filename[ZX_MAX_NAME_LEN];
        snprintf(filename, sizeof(filename), "%s.%" PRIu64, data.sink_name.c_str(), info.koid);

        fbl::unique_fd fd{openat(sink_dir_fd.get(), filename, O_WRONLY | O_CREAT | O_EXCL, 0666)};
        if (!fd) {
            fprintf(stderr, "FAILURE: Cannot open data-sink file \"%s\": %s\n",
                    data.sink_name.c_str(), strerror(errno));
            if (result->return_code == 0) {
                result->launch_status = FAILED_COLLECTING_SINK_DATA;
            }
            continue;
        }
        // Strip any leading slashes (including a sequence of slashes) so the dump
        // file path is a relative to directory that contains the summary file.
        size_t i = strspn(path, "/");
        auto dump_file = JoinPath(&path[i], JoinPath(data.sink_name, filename));

        uint8_t *buf = reinterpret_cast<uint8_t *>(mapping);
        ssize_t count = size;
        ssize_t len = 0;
        while (count > 0 && (len = write(fd.get(), buf, count)) != count) {
            if (len == -1) {
                fprintf(stderr, "FAILURE: Cannot write data to \"%s\": %s\n",
                        dump_file.c_str(), strerror(errno));
                if (result->return_code == 0) {
                    result->launch_status = FAILED_COLLECTING_SINK_DATA;
                }
                break;
            }
            count -= len;
            buf += len;
        }
        if (len == -1) {
            continue;
        }

        char name[ZX_MAX_NAME_LEN];
        status = data.file_data.get_property(ZX_PROP_NAME, name, sizeof(name));
        if (status != ZX_OK) {
            if (result->return_code == 0) {
                result->launch_status = FAILED_COLLECTING_SINK_DATA;
            }
            continue;
        }
        if (name[0] == '\0') {
            snprintf(name, sizeof(name), "unnamed.%" PRIu64, info.koid);
        }

        Result::HashTable::iterator it;
        result->data_sinks.insert_or_find(std::make_unique<DataSink>(data.sink_name), &it);
        it->files.push_back(DumpFile{name, dump_file});
    }

    return result;
}

} // namespace runtests
