/*
 * 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.
 *
 * Authors: Andreas Sandberg
 */

#ifndef __DEV_VIRTIO_FS9P_HH__
#define __DEV_VIRTIO_FS9P_HH__

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

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

struct VirtIO9PBaseParams;

typedef uint8_t P9MsgType;
typedef uint16_t P9Tag;

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

/** 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(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 Config {
        uint16_t len;
        char tag[];
    } M5_ATTR_PACKED;

    /** 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(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(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(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;
};

#endif // __DEV_VIRTIO_FS9P_HH__
