// 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 VmoFromFd(fbl::unique_fd fd, const char* file_name, zx_handle_t* out) {
    zx_status_t status = fdio_get_vmo_clone(fd.get(), out);
    if (status != ZX_OK) {
        return status;
    }
    return zx_object_set_property(*out, ZX_PROP_NAME, file_name, strlen(file_name));
}

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 VmoFromFd(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 VmoFromFd(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);
        }
        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
