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

#pragma once

#include <fbl/unique_fd.h>
#include <map>
#include <poll.h>
#include <set>
#include <vector>

#include "usb-handler.h"

namespace xdc {

class Client {
public:
    explicit Client(int fd) : fd_(fd) {}

    void SetStreamId(uint32_t stream_id);
    void SetConnected(bool connected);
    // Returns whether the set of client events we are polling for has changed.
    bool UpdatePollState();

    // Queues a completed read transfer to be written to the client.
    void AddCompletedRead(std::unique_ptr<UsbHandler::Transfer> transfer);
    // Writes data from completed read transfers to the client until there are
    // no transfers left, or the client is currently unavailable to accept data.
    void ProcessCompletedReads(const std::unique_ptr<UsbHandler>& usb_handler);
    // Returns any unused transfers to the usb handler.
    void ReturnTransfers(const std::unique_ptr<UsbHandler>& usb_handler);

    int fd()             const { return fd_.get(); }
    // Returns the set of client events we should poll for.
    short events()       const { return events_; }
    bool registered()    const { return registered_; }
    uint32_t stream_id() const { return stream_id_; }
    bool connected()     const { return connected_; }

private:
    fbl::unique_fd fd_;

    short events_ = 0;

    // Whether the client has registered a stream id.
    bool     registered_ = false;
    uint32_t stream_id_  = 0;
    // True if the client has registered a stream id,
    // and that stream id is also registered on the xdc device side.
    bool     connected_  = false;
    std::vector<std::unique_ptr<UsbHandler::Transfer>> completed_reads_;
};

class XdcServer {
    // This is required by the XdcServer constructor, to stop clients calling it directly.
    struct ConstructorTag { explicit ConstructorTag() = default; };

public:
    // Create should be called instead. This is public for make_unique.
    XdcServer(ConstructorTag tag) {}

    static std::unique_ptr<XdcServer> Create();
    void Run();

private:
    bool Init();

    void UpdateClientPollEvents();

    // Updates poll_fds_ with any newly added or removed usb handler fds.
    void UpdateUsbHandlerFds();

    // Processes new client connections on the server socket.
    void ClientConnect();

    // Returns whether registration succeeded.
    bool RegisterStream(std::shared_ptr<Client> client);

    // Returns the client registered to the given stream id, or nullptr if none was foumd.
    std::shared_ptr<Client> GetClient(uint32_t stream_id);

    void UsbReadComplete(std::unique_ptr<UsbHandler::Transfer> transfer);
    // Parses the control message from the given transfer buffer.
    void HandleCtrlMsg(unsigned char* transfer_buf, int transfer_len);

    // Sends a control message the to the xdc device with whether a stream has gone on / offline.
    // If the message cannot currently be sent, it is queued to be retried later.
    void NotifyStreamState(uint32_t stream_id, bool online);
    bool SendCtrlMsg(xdc_msg_t& msg);
    void SendQueuedCtrlMsgs();

    std::unique_ptr<UsbHandler> usb_handler_;

    // Server socket we receive client connections on.
    fbl::unique_fd socket_fd_;
    // File lock acquired to ensure we don't unlink the socket of a running xdc server instance.
    fbl::unique_fd socket_lock_fd_;

    // Maps from client socket file descriptor to client.
    std::map<int, std::shared_ptr<Client>> clients_;

    // File descriptors we are currently polling on.
    std::vector<pollfd> poll_fds_;

    // Stream ids registered on the xdc device side.
    std::set<uint32_t> dev_stream_ids_;

    std::vector<xdc_msg_t> queued_ctrl_msgs_;

    xdc_packet_state_t read_packet_state_;
};

}  // namespace xdc
