// Copyright 2019 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 "paver.h"

#include <algorithm>

#include <fbl/auto_call.h>
#include <lib/async-loop/cpp/loop.h>
#include <lib/fdio/directory.h>
#include <lib/zx/time.h>
#include <zircon/boot/netboot.h>

#include "payload-streamer.h"

namespace netsvc {
namespace {

size_t NB_IMAGE_PREFIX_LEN() {
    return strlen(NB_IMAGE_PREFIX);
}
size_t NB_FILENAME_PREFIX_LEN() {
    return strlen(NB_FILENAME_PREFIX);
}

} // namespace

Paver* Paver::Get() {
    static Paver* instance_ = nullptr;
    if (instance_ == nullptr) {
        zx::channel local, remote;
        auto status = zx::channel::create(0, &local, &remote);
        if (status != ZX_OK) {
            return nullptr;
        }
        status = fdio_service_connect("/svc", remote.release());
        if (status != ZX_OK) {
            return nullptr;
        }
        instance_ = new Paver(std::move(local));
    }
    return instance_;
}

bool Paver::InProgress() {
    return in_progress_.load();
}
zx_status_t Paver::exit_code() {
    return exit_code_.load();
}
void Paver::reset_exit_code() {
    exit_code_.store(ZX_OK);
}

int Paver::StreamBuffer() {
    zx::time last_reported = zx::clock::get_monotonic();
    int result = 0;
    auto callback = [this, &last_reported, &result](void* buf, size_t read_offset,
                                                    size_t size, size_t* actual) {
        if (read_offset >= size_) {
            *actual = 0;
            return ZX_OK;
        }
        sync_completion_reset(&data_ready_);
        size_t write_offset = write_offset_.load();
        while (write_offset == read_offset) {
            // Wait for more data to be written -- we are allowed up to 3 tftp timeouts before
            // a connection is dropped, so we should wait at least that long before giving up.
            auto status = sync_completion_wait(&data_ready_, timeout_.get());
            if (status != ZX_OK) {
                printf("netsvc: 1 timed out while waiting for data in paver-copy thread\n");
                exit_code_.store(status);
                result = TFTP_ERR_TIMED_OUT;
                return ZX_ERR_TIMED_OUT;
            }
            sync_completion_reset(&data_ready_);
            write_offset = write_offset_.load();
        };
        size = std::min(size, write_offset - read_offset);
        memcpy(buf, buffer() + read_offset, size);
        *actual = size;
        zx::time curr_time = zx::clock::get_monotonic();
        if (curr_time - last_reported >= zx::sec(1)) {
            float complete =
                (static_cast<float>(read_offset) / static_cast<float>(size_)) *
                100.f;
            printf("netsvc: paver write progress %0.1f%%\n", complete);
            last_reported = curr_time;
        }
        return ZX_OK;
    };

    fbl::AutoCall cleanup([this, &result]() {
        unsigned int refcount = std::atomic_fetch_sub(&buf_refcount_, 1u);
        if (refcount == 1) {
            buffer_mapper_.Reset();
        }

        paver_svc_.reset();

        if (result != 0) {
            printf("netsvc: copy exited prematurely (%d): expect paver errors\n", result);
        }

        in_progress_.store(false);
    });

    zx::channel client, server;
    auto status = zx::channel::create(0, &client, &server);
    if (status) {
        fprintf(stderr, "netsvc: unable to create channel\n");
        exit_code_.store(status);
        return 0;
    }

    async::Loop loop(&kAsyncLoopConfigAttachToThread);
    PayloadStreamer streamer(std::move(server), std::move(callback));
    loop.StartThread("payload-streamer");

    // Blocks untils paving is complete.
    auto io_status = fuchsia_paver_PaverWriteVolumes(paver_svc_.get(), client.release(),
                                                     &status);
    status = io_status == ZX_OK ? status : io_status;
    exit_code_.store(status);

    return 0;
}

int Paver::MonitorBuffer() {
    int result = TFTP_NO_ERROR;

    fbl::AutoCall cleanup([this, &result]() {
        unsigned int refcount = std::atomic_fetch_sub(&buf_refcount_, 1u);
        if (refcount == 1) {
            buffer_mapper_.Reset();
        }

        paver_svc_.reset();

        if (result != 0) {
            printf("netsvc: copy exited prematurely (%d): expect paver errors\n", result);
        }

        in_progress_.store(false);
    });

    size_t write_ndx = 0;
    do {
        // Wait for more data to be written -- we are allowed up to 3 tftp timeouts before
        // a connection is dropped, so we should wait at least that long before giving up.
        auto status = sync_completion_wait(&data_ready_, timeout_.get());
        if (status != ZX_OK) {
            printf("netsvc: 2 timed out while waiting for data in paver-copy thread\n");
            exit_code_.store(status);
            result = TFTP_ERR_TIMED_OUT;
            return result;
        }
        sync_completion_reset(&data_ready_);
        write_ndx = write_offset_.load();
    } while (write_ndx < size_);

    zx::vmo dup;
    auto status = buffer_mapper_.vmo().duplicate(ZX_RIGHT_SAME_RIGHTS, &dup);
    if (status != ZX_OK) {
        exit_code_.store(status);
        return 0;
    }

    fuchsia_mem_Buffer buffer = {
        .vmo = dup.release(),
        .size = buffer_mapper_.size(),
    };

    zx_status_t io_status = ZX_ERR_INTERNAL;
    // Blocks untils paving is complete.
    switch (command_) {
    case Command::kDataFile:
        io_status = fuchsia_paver_PaverWriteDataFile(paver_svc_.get(), path_, strlen(path_),
                                                     &buffer, &status);
        break;
    case Command::kBootloader:
        io_status = fuchsia_paver_PaverWriteBootloader(paver_svc_.get(), &buffer, &status);
        break;
    case Command::kAsset:
        io_status = fuchsia_paver_PaverWriteAsset(paver_svc_.get(), configuration_, asset_, &buffer,
                                                  &status);
        break;
    default:
        io_status = ZX_OK;
        result = TFTP_ERR_INTERNAL;
        status = ZX_ERR_INTERNAL;
        break;
    }
    status = io_status == ZX_OK ? status : io_status;
    exit_code_.store(status);

    return 0;
}

tftp_status Paver::OpenWrite(const char* filename, size_t size) {
    // Paving an image to disk.
    if (!strcmp(filename + NB_IMAGE_PREFIX_LEN(), NB_FVM_HOST_FILENAME)) {
        printf("netsvc: Running FVM Paver\n");
        command_ = Command::kFvm;
    } else if (!strcmp(filename + NB_IMAGE_PREFIX_LEN(), NB_BOOTLOADER_HOST_FILENAME)) {
        printf("netsvc: Running BOOTLOADER Paver\n");
        command_ = Command::kBootloader;
    } else if (!strcmp(filename + NB_IMAGE_PREFIX_LEN(), NB_ZIRCONA_HOST_FILENAME)) {
        printf("netsvc: Running ZIRCON-A Paver\n");
        command_ = Command::kAsset;
        configuration_ = fuchsia_paver_Configuration_A;
        asset_ = fuchsia_paver_Asset_KERNEL;
    } else if (!strcmp(filename + NB_IMAGE_PREFIX_LEN(), NB_ZIRCONB_HOST_FILENAME)) {
        printf("netsvc: Running ZIRCON-B Paver\n");
        command_ = Command::kAsset;
        configuration_ = fuchsia_paver_Configuration_B;
        asset_ = fuchsia_paver_Asset_KERNEL;
    } else if (!strcmp(filename + NB_IMAGE_PREFIX_LEN(), NB_ZIRCONR_HOST_FILENAME)) {
        printf("netsvc: Running ZIRCON-R Paver\n");
        command_ = Command::kAsset;
        configuration_ = fuchsia_paver_Configuration_RECOVERY;
        asset_ = fuchsia_paver_Asset_KERNEL;
    } else if (!strcmp(filename + NB_IMAGE_PREFIX_LEN(), NB_VBMETAA_HOST_FILENAME)) {
        printf("netsvc: Running VBMETA-A Paver\n");
        command_ = Command::kAsset;
        configuration_ = fuchsia_paver_Configuration_A;
        asset_ = fuchsia_paver_Asset_VERIFIED_BOOT_METADATA;
    } else if (!strcmp(filename + NB_IMAGE_PREFIX_LEN(), NB_VBMETAB_HOST_FILENAME)) {
        printf("netsvc: Running VBMETA-B Paver\n");
        command_ = Command::kAsset;
        configuration_ = fuchsia_paver_Configuration_B;
        asset_ = fuchsia_paver_Asset_VERIFIED_BOOT_METADATA;
    } else if (!strcmp(filename + NB_IMAGE_PREFIX_LEN(), NB_VBMETAR_HOST_FILENAME)) {
        printf("netsvc: Running VBMETA-R Paver\n");
        command_ = Command::kAsset;
        configuration_ = fuchsia_paver_Configuration_RECOVERY;
        asset_ = fuchsia_paver_Asset_VERIFIED_BOOT_METADATA;
    } else if (!strcmp(filename + NB_IMAGE_PREFIX_LEN(), NB_SSHAUTH_HOST_FILENAME)) {
        printf("netsvc: Installing SSH authorized_keys\n");
        command_ = Command::kDataFile;
        strncpy(path_, "ssh/authorized_keys", PATH_MAX);
    } else {
        fprintf(stderr, "netsvc: Unknown Paver\n");
        return TFTP_ERR_IO;
    }

    auto status = buffer_mapper_.CreateAndMap(size, "paver");
    if (status != ZX_OK) {
        printf("netsvc: unable to allocate and map buffer\n");
        return status;
    }
    fbl::AutoCall buffer_cleanup([this]() { buffer_mapper_.Reset(); });

    zx::channel paver_local, paver_remote;
    status = zx::channel::create(0, &paver_local, &paver_remote);
    if (status != ZX_OK) {
        fprintf(stderr, "netsvc: Unable to create channel pair.\n");
        return TFTP_ERR_IO;
    }
    status = fdio_service_connect_at(svc_root_.get(), fuchsia_paver_Paver_Name,
                                     paver_remote.release());
    if (status != ZX_OK) {
        fprintf(stderr, "netsvc: Unable to open /svc/%s.\n", fuchsia_paver_Paver_Name);
        return TFTP_ERR_IO;
    }

    paver_svc_ = std::move(paver_local);
    fbl::AutoCall svc_cleanup([&]() { paver_svc_.reset(); });

    size_ = size;

    buf_refcount_.store(2u);
    write_offset_.store(0ul);
    exit_code_.store(0);
    in_progress_.store(true);

    sync_completion_reset(&data_ready_);

    auto thread_fn = command_ == Command::kFvm
                         ? [](void* arg) { return static_cast<Paver*>(arg)->StreamBuffer(); }
                         : [](void* arg) { return static_cast<Paver*>(arg)->MonitorBuffer(); };
    if (thrd_create(&buf_thrd_, thread_fn, this) != thrd_success) {
        fprintf(stderr, "netsvc: unable to launch buffer stream/monitor thread\n");
        status = ZX_ERR_NO_RESOURCES;
        return status;
    }
    thrd_detach(buf_thrd_);
    svc_cleanup.cancel();
    buffer_cleanup.cancel();

    return TFTP_NO_ERROR;
}

tftp_status Paver::Write(const void* data, size_t* length, off_t offset) {
    if (!InProgress()) {
        printf("netsvc: paver exited prematurely with %d\n", exit_code());
        reset_exit_code();
        return TFTP_ERR_IO;
    }

    if ((static_cast<size_t>(offset) > size_) ||
        (offset + *length) > size_) {
        return TFTP_ERR_INVALID_ARGS;
    }
    memcpy(&buffer()[offset], data, *length);
    size_t new_offset = offset + *length;
    write_offset_.store(new_offset);
    // Wake the paver thread, if it is waiting for data
    sync_completion_signal(&data_ready_);
    return TFTP_NO_ERROR;
}

void Paver::Close() {
    unsigned int refcount = std::atomic_fetch_sub(&buf_refcount_, 1u);
    if (refcount == 1) {
        buffer_mapper_.Reset();
    }
    // TODO: Signal thread to wake up rather than wait for it to timeout if
    // stream is closed before write is complete?
}

} // namespace netsvc
