/*
 * Copyright (c) 2014-2017 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __DEV_VIRTIO_FS9P_HH__
#define __DEV_VIRTIO_FS9P_HH__

#include <map>
#include <memory>
#include <string>

#include "base/compiler.hh"
#include "base/pollevent.hh"
#include "dev/virtio/base.hh"

namespace gem5
{

struct VirtIO9PBaseParams;

typedef uint8_t P9MsgType;
typedef uint16_t P9Tag;

struct GEM5_PACKED P9MsgHeader
{
    /** Length including header */
    uint32_t len;
    /** Message type */
    P9MsgType type;
    /** Message tag */
    P9Tag tag;
};

/** Convert p9 byte order (LE) to host byte order */
template <typename T> inline T
p9toh(T v) { return letoh(v); }

/** Convert host byte order to p9 byte order (LE) */
template <typename T> inline T
htop9(T v) { return htole(v); }

template <> inline P9MsgHeader
p9toh(P9MsgHeader v)
{
    v.len = p9toh(v.len);
    v.type = p9toh(v.type);
    v.tag = p9toh(v.tag);
    return v;
}

template <> inline P9MsgHeader
htop9(P9MsgHeader v)
{
    v.len = htop9(v.len);
    v.type = htop9(v.type);
    v.tag = htop9(v.tag);
    return v;
}

/**
 * This class implements a VirtIO transport layer for the 9p network
 * file system.
 *
 * The 9p VirtIO transport uses the following queues:
 *  -# 9p requests and replies
 *
 * Each 9p request and response is sent in its own descriptor
 * chain. The guest initiates a transaction by packing a T message
 * (see the 9p spec) into the first part of a descriptor chain. After
 * the T message, the guest reserves space for the reply (R message)
 * by including one or more writable descriptors. The server replies
 * by writing an R message into the writable descriptors and putting
 * the chain in the used ring (VirtQueue::produceDescriptor()).
 *
 * @see https://github.com/rustyrussell/virtio-spec
 * @see https://github.com/ericvh/9p-rfc
 * @see https://code.google.com/p/diod/wiki/protocol
 */
class VirtIO9PBase : public VirtIODeviceBase
{
  public:
    typedef VirtIO9PBaseParams Params;
    VirtIO9PBase(const Params &params);
    virtual ~VirtIO9PBase();

    void readConfig(PacketPtr pkt, Addr cfgOffset);

  protected:
    /**
     * VirtIO 9p configuration structure
     *
     * @note The fields in this structure depend on the features
     * exposed to the guest.
     */
    struct GEM5_PACKED Config
    {
        uint16_t len;
        char tag[];
    };

    /** Currently active configuration (host byte order) */
    std::unique_ptr<Config> config;

    /** VirtIO device ID */
    static const DeviceId ID_9P = 0x09;

    /** @{
     * @name Feature bits
     */
    /** Device provides a name of the resource in its configuration */
    static const FeatureBits F_MOUNT_TAG = 0x01;
    /** @} */

  protected:
    /**
     * Virtqueue for 9p requests
     */
    class FSQueue : public VirtQueue
    {
      public:
        FSQueue(PortProxy &proxy, ByteOrder bo,
                uint16_t size, VirtIO9PBase &_parent)
            : VirtQueue(proxy, bo, size), parent(_parent) {}
        virtual ~FSQueue() {}

        void onNotifyDescriptor(VirtDescriptor *desc);

        std::string name() const { return parent.name() + ".queue"; }

      protected:
        VirtIO9PBase &parent;
    };

    FSQueue queue;

  protected:
    /**
     * Handle incoming 9p RPC message.
     *
     * @param header 9p message header.
     * @param data Pointer to data in message.
     * @param size Size of data (excluding header)
     */
    virtual void recvTMsg(const P9MsgHeader &header, const uint8_t *data, size_t size) = 0;
    /**
     * Send a 9p RPC message reply.
     *
     * @param header 9p message header.
     * @param data Pointer to data in message.
     * @param size Size of data (excluding header)
     */
    void sendRMsg(const P9MsgHeader &header, const uint8_t *data, size_t size);

    /**
     * Dump a 9p RPC message on the debug output
     *
     * @param header 9p message header.
     * @param data Pointer to data in message.
     * @param size Size of data (excluding header)
     */
    void dumpMsg(const P9MsgHeader &header, const uint8_t *data, size_t size);

  private:
    /**
     * Map between 9p transaction tags and descriptors where they
     * appeared.
     *
     * When handling asynchronous requests, we need to ensure that
     * replies are posted in the same descriptor as queries. The 9p
     * RPC protocol uses the tag field in the header to match requests
     * and replies, which we use here to find the relevant descriptor.
     */
    std::map<P9Tag, VirtDescriptor *> pendingTransactions;
};

struct VirtIO9PProxyParams;

/**
 * VirtIO 9p proxy base class.
 *
 * This base class provides basic functionality shared by different 9p
 * proxy implementations.
 */
class VirtIO9PProxy : public VirtIO9PBase
{
  public:
    typedef VirtIO9PProxyParams Params;
    VirtIO9PProxy(const Params &params);
    virtual ~VirtIO9PProxy();

    void serialize(CheckpointOut &cp) const override;
    void unserialize(CheckpointIn &cp) override;

  protected:
    void recvTMsg(const P9MsgHeader &header, const uint8_t *data,
                  size_t size) override;

    /** Notification of pending data from server */
    void serverDataReady();

    /**
     * Read data from the server behind the proxy.
     *
     * @note This method may return read fewer than len bytes.
     *
     * @param data Memory location to store results in.
     * @param len Maximum length to read.
     * @return Number of bytes read, -errno on failure.
     */
    virtual ssize_t read(uint8_t *data, size_t len) = 0;
    /**
     * Write data to the server behind the proxy.
     *
     * @note This method may return write fewer than len bytes.
     *
     * @param data Pointer to data to write.
     * @param len Maximum length to write.
     * @return Number of bytes written, -errno on failure.
     */
    virtual ssize_t write(const uint8_t *data, size_t len) = 0;

    /**
     * Convenience function that reads exactly len bytes.
     *
     * This method calls read until exactly len number of bytes has
     * been read. A read() call is retried if the underlying syscall
     * was interrupted.
     *
     * @param data Memory location to store results in.
     * @param len Number of bytes to read.
     */
    void readAll(uint8_t *data, size_t len);
    /**
     * Convenience function that writes exactly len bytes.
     *
     * This method calls write until exactly len number of bytes has
     * been written. A write() call is retried if the underlying
     * syscall was interrupted.
     *
     * @param data Data to write.
     * @param len Number of bytes to write.
     */
    void writeAll(const uint8_t *data, size_t len);

    /**
     * Bool to track if the device has been used or not.
     *
     * We need to keep track of if the device has been used as we are
     * unable to checkpoint the device in the event that the device
     * has been mounted in the guest system. This is due to the fact
     * that we do not, and cannot, track the complete state across
     * host and guest.
     */
     bool deviceUsed;
};

struct VirtIO9PDiodParams;

/**
 * VirtIO 9p proxy that communicates with the diod 9p server using
 * pipes.
 */
class VirtIO9PDiod : public VirtIO9PProxy
{
  public:
    typedef VirtIO9PDiodParams Params;
    VirtIO9PDiod(const Params &params);
    virtual ~VirtIO9PDiod();

    void startup();

  protected:
    /**
     * Start diod and setup the communication pipes.
     */
    void startDiod();

    ssize_t read(uint8_t *data, size_t len);
    ssize_t write(const uint8_t *data, size_t len);
    /** Kill the diod child process at the end of the simulation */
    void terminateDiod();

  private:
    class DiodDataEvent : public PollEvent
    {
      public:
        DiodDataEvent(VirtIO9PDiod &_parent, int fd, int event)
            : PollEvent(fd, event), parent(_parent) {}

        virtual ~DiodDataEvent() {};

        void process(int revent);

      private:
        VirtIO9PDiod &parent;
    };

    /** fd for data pipe going to diod (write end) */
    int fd_to_diod;
    /** fd for data pipe coming from diod (read end) */
    int fd_from_diod;

    std::unique_ptr<DiodDataEvent> dataEvent;

    /** PID of diod process */
    int diod_pid;
};

struct VirtIO9PSocketParams;

/**
 * VirtIO 9p proxy that communicates with a 9p server over tcp
 * sockets.
 */
class VirtIO9PSocket : public VirtIO9PProxy
{
  public:
    typedef VirtIO9PSocketParams Params;
    VirtIO9PSocket(const Params &params);
    virtual ~VirtIO9PSocket();

    void startup();

  protected:
    /**
     * Try to resolve the server name and connect to the 9p server.
     */
    void connectSocket();

    /** 9p server disconnect notification */
    void socketDisconnect();

    ssize_t read(uint8_t *data, size_t len);
    ssize_t write(const uint8_t *data, size_t len);

  private:
    class SocketDataEvent : public PollEvent
    {
      public:
        SocketDataEvent(VirtIO9PSocket &_parent, int fd, int event)
            : PollEvent(fd, event), parent(_parent) {}

        virtual ~SocketDataEvent() {};

        void process(int revent);

      private:
        VirtIO9PSocket &parent;
    };

    /** Socket connected to the 9p server */
    int fdSocket;

    std::unique_ptr<SocketDataEvent> dataEvent;
};

} // namespace gem5

#endif // __DEV_VIRTIO_FS9P_HH__
