// 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.

#pragma once

#include <atomic>
#include <threads.h>

#include <limits.h>

#include <fuchsia/paver/c/fidl.h>
#include <lib/fzl/owned-vmo-mapper.h>
#include <lib/sync/completion.h>
#include <lib/zx/channel.h>
#include <lib/zx/time.h>
#include <tftp/tftp.h>
#include <zircon/types.h>

#include "tftp.h"

namespace netsvc {

class PaverInterface {
public:
    virtual bool InProgress() = 0;
    virtual zx_status_t exit_code() = 0;
    virtual void reset_exit_code() = 0;

    // TODO: Explore returning an object which implements write and when it goes
    // out of scope, closes.
    virtual tftp_status OpenWrite(const char* filename, size_t size) = 0;
    virtual tftp_status Write(const void* data, size_t* length, off_t offset) = 0;
    virtual void Close() = 0;
};

class Paver : public PaverInterface {
public:
    // Get the singleton instance.
    static Paver* Get();

    bool InProgress() final;
    zx_status_t exit_code() final;
    void reset_exit_code() final;

    tftp_status OpenWrite(const char* filename, size_t size) final;
    tftp_status Write(const void* data, size_t* length, off_t offset) final;
    void Close() final;

    // Visible for testing.
    explicit Paver(zx::channel svc_root)
        : svc_root_(std::move(svc_root)) {}

    void set_timeout(zx::duration timeout) { timeout_ = timeout; }

private:
    // Refer to //zircon/system/fidl/fuchsia.paver/paver.fidl for a list of what
    // these commands translate to.
    enum class Command {
        kAsset,
        kBootloader,
        kDataFile,
        kFvm,
    };

    uint8_t* buffer() { return static_cast<uint8_t*>(buffer_mapper_.start()); }

    // Pushes all data from the paver buffer (filled by netsvc) into the paver input VMO. When
    // there's no data to copy, blocks on data_ready until more data is written into the buffer.
    int StreamBuffer();

    // Monitors the vmo progress, and calls into paver service once finished.
    int MonitorBuffer();

    std::atomic<bool> in_progress_ = false;
    std::atomic<zx_status_t> exit_code_ = ZX_OK;

    // Total size of file
    size_t size_ = 0;

    // Paver command to call into.
    Command command_;

    // Channel to svc.
    zx::channel svc_root_;

    // Channel to paver service.
    zx::channel paver_svc_;

    union {
        // Only valid when command == Command::kAsset.
        struct {
            fuchsia_paver_Configuration configuration_;
            fuchsia_paver_Asset asset_;
        };
        // Only valid when command == Command::kDataFile.
        char path_[PATH_MAX];
    };

    // Buffer used for stashing data from tftp until it can be written out to the paver.
    fzl::OwnedVmoMapper buffer_mapper_;
    // Buffer write offset.
    std::atomic<size_t> write_offset_ = 0;
    std::atomic<unsigned int> buf_refcount_ = 0;
    thrd_t buf_thrd_ = 0;
    sync_completion_t data_ready_;

    // Timeout monitor thread uses before timing out.
    zx::duration timeout_ = zx::sec(5 * TFTP_TIMEOUT_SECS);
};

} // namespace netsvc
