/*
 * Copyright (c) 2010, 2015 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.
 */

/** @file
 * Implementiation of a VNC server
 */

#include <sys/ioctl.h>
#include <sys/stat.h>

#if defined(__FreeBSD__)
#include <termios.h>

#else
#include <sys/termios.h>

#endif
#include "base/vnc/vncserver.hh"

#include <fcntl.h>
#include <poll.h>
#include <sys/types.h>
#include <unistd.h>

#include <cerrno>
#include <cstddef>
#include <cstdio>

#include "base/atomicio.hh"
#include "base/logging.hh"
#include "base/output.hh"
#include "base/socket.hh"
#include "base/trace.hh"
#include "debug/VNC.hh"
#include "sim/byteswap.hh"
#include "sim/core.hh"

const PixelConverter VncServer::pixelConverter(
    4,        // 4 bytes / pixel
    16, 8, 0, // R in [23, 16], G in [15, 8], B in [7, 0]
    8, 8, 8,  // 8 bits / channel
    ByteOrder::little);

/** @file
 * Implementiation of a VNC server
 */

/**
 * Poll event for the listen socket
 */
VncServer::ListenEvent::ListenEvent(VncServer *vs, int fd, int e)
    : PollEvent(fd, e), vncserver(vs)
{
}

void
VncServer::ListenEvent::process(int revent)
{
    vncserver->accept();
}

/**
 * Poll event for the data socket
 */
VncServer::DataEvent::DataEvent(VncServer *vs, int fd, int e)
    : PollEvent(fd, e), vncserver(vs)
{
}

void
VncServer::DataEvent::process(int revent)
{
    if (revent & POLLIN)
        vncserver->data();
    else if (revent & POLLNVAL)
        vncserver->detach();
}

/**
 * VncServer
 */
VncServer::VncServer(const Params &p)
    : VncInput(p), listenEvent(NULL), dataEvent(NULL), number(p.number),
      dataFd(-1), sendUpdate(false),
      supportsRawEnc(false), supportsResizeEnc(false)
{
    if (p.port)
        listen(p.port);

    curState = WaitForProtocolVersion;

    // We currently only support one pixel format. Extract the pixel
    // representation from our PixelConverter instance and keep it
    // around for telling the client and making sure it cooperates
    pixelFormat.bpp = 8 * pixelConverter.length;
    pixelFormat.depth = pixelConverter.depth;
    pixelFormat.bigendian = pixelConverter.byte_order == ByteOrder::big;
    pixelFormat.truecolor = 1;
    pixelFormat.redmax = pixelConverter.ch_r.mask;
    pixelFormat.greenmax = pixelConverter.ch_g.mask;
    pixelFormat.bluemax = pixelConverter.ch_b.mask;
    pixelFormat.redshift = pixelConverter.ch_r.offset;
    pixelFormat.greenshift = pixelConverter.ch_g.offset;
    pixelFormat.blueshift = pixelConverter.ch_b.offset;

    DPRINTF(VNC, "Vnc server created at port %d\n", p.port);
}

VncServer::~VncServer()
{
    if (dataFd != -1)
        ::close(dataFd);

    if (listenEvent)
        delete listenEvent;

    if (dataEvent)
        delete dataEvent;
}


//socket creation and vnc client attach
void
VncServer::listen(int port)
{
    if (ListenSocket::allDisabled()) {
        warn_once("Sockets disabled, not accepting vnc client connections");
        return;
    }

    while (!listener.listen(port, true)) {
        DPRINTF(VNC,
                "can't bind address vnc server port %d in use PID %d\n",
                port, getpid());
        port++;
    }

    ccprintf(std::cerr, "%s: Listening for connections on port %d\n",
             name(), port);

    listenEvent = new ListenEvent(this, listener.getfd(), POLLIN);
    pollQueue.schedule(listenEvent);
}

// attach a vnc client
void
VncServer::accept()
{
    // As a consequence of being called from the PollQueue, we might
    // have been called from a different thread. Migrate to "our"
    // thread.
    EventQueue::ScopedMigration migrate(eventQueue());

    if (!listener.islistening())
        panic("%s: cannot accept a connection if not listening!", name());

    int fd = listener.accept(true);
    if (fd < 0) {
        warn("%s: failed to accept VNC connection!", name());
        return;
    }

    if (dataFd != -1) {
        char message[] = "vnc server already attached!\n";
        atomic_write(fd, message, sizeof(message));
        ::close(fd);
        return;
    }

    dataFd = fd;

    // Send our version number to the client
    write((uint8_t *)vncVersion(), strlen(vncVersion()));

    // read the client response
    dataEvent = new DataEvent(this, dataFd, POLLIN);
    pollQueue.schedule(dataEvent);

    inform("VNC client attached\n");
}

// data called by data event
void
VncServer::data()
{
    // We have new data, see if we can handle it
    DPRINTF(VNC, "Vnc client message recieved\n");

    switch (curState) {
      case WaitForProtocolVersion:
        checkProtocolVersion();
        break;
      case WaitForSecurityResponse:
        checkSecurity();
        break;
      case WaitForClientInit:
        // Don't care about shared, just need to read it out of the socket
        uint8_t shared;
        if (!read(&shared))
            return;

        // Send our idea of the frame buffer
        sendServerInit();

        break;
      case NormalPhase:
        uint8_t message_type;
        if (!read(&message_type))
            return;

        switch (message_type) {
          case ClientSetPixelFormat:
            setPixelFormat();
            break;
          case ClientSetEncodings:
            setEncodings();
            break;
          case ClientFrameBufferUpdate:
            requestFbUpdate();
            break;
          case ClientKeyEvent:
            recvKeyboardInput();
            break;
          case ClientPointerEvent:
            recvPointerInput();
            break;
          case ClientCutText:
            recvCutText();
            break;
          default:
            warn("Unimplemented message type recv from client: %d\n",
                 message_type);
            detach();
            break;
        }
        break;
      default:
        panic("Unknown vnc server state\n");
    }
}


// read from socket
bool
VncServer::read(uint8_t *buf, size_t len)
{
    if (dataFd < 0)
        panic("vnc not properly attached.\n");

    size_t ret;
    do {
        ret = ::read(dataFd, buf, len);
    } while (ret == -1 && errno == EINTR);


    if (ret != len) {
        DPRINTF(VNC, "Read failed %d.\n", ret);
        detach();
        return false;
    }

    return true;
}

bool
VncServer::read1(uint8_t *buf, size_t len)
{
    return read(buf + 1, len - 1);
}


template<typename T>
bool
VncServer::read(T* val)
{
    return read((uint8_t *)val, sizeof(T));
}

// write to socket
bool
VncServer::write(const uint8_t *buf, size_t len)
{
    if (dataFd < 0)
        panic("Vnc client not properly attached.\n");

    ssize_t ret = atomic_write(dataFd, buf, len);

    if (ret != len) {
        DPRINTF(VNC, "Write failed.\n");
        detach();
        return false;
    }

    return true;
}

template<typename T>
bool
VncServer::write(T* val)
{
    return write((uint8_t *)val, sizeof(T));
}

bool
VncServer::write(const char* str)
{
    return write((uint8_t *)str, strlen(str));
}

// detach a vnc client
void
VncServer::detach()
{
    if (dataFd != -1) {
        ::close(dataFd);
        dataFd = -1;
    }

    if (!dataEvent || !dataEvent->queued())
        return;

    pollQueue.remove(dataEvent);
    delete dataEvent;
    dataEvent = NULL;
    curState = WaitForProtocolVersion;

    inform("VNC client detached\n");
    DPRINTF(VNC, "detach vnc client %d\n", number);
}

void
VncServer::sendError(const char* error_msg)
{
   uint32_t len = strlen(error_msg);
   if (!write(&len))
       return;
   write(error_msg);
}

void
VncServer::checkProtocolVersion()
{
    assert(curState == WaitForProtocolVersion);

    M5_VAR_USED size_t len;
    char version_string[13];

    // Null terminate the message so it's easier to work with
    version_string[12] = 0;

    if (!read((uint8_t *)version_string, sizeof(version_string) - 1)) {
        warn("Failed to read protocol version.");
        return;
    }

    uint32_t major, minor;

    // Figure out the major/minor numbers
    if (sscanf(version_string, "RFB %03d.%03d\n", &major, &minor) != 2) {
        warn(" Malformed protocol version %s\n", version_string);
        sendError("Malformed protocol version\n");
        detach();
        return;
    }

    DPRINTF(VNC, "Client request protocol version %d.%d\n", major, minor);

    // If it's not 3.X we don't support it
    if (major != 3 || minor < 2) {
        warn("Unsupported VNC client version... disconnecting\n");
        uint8_t err = AuthInvalid;
        write(&err);
        detach();
        return;
    }
    // Auth is different based on version number
    if (minor < 7) {
        uint32_t sec_type = htobe((uint32_t)AuthNone);
        if (!write(&sec_type))
            return;
    } else {
        uint8_t sec_cnt = 1;
        uint8_t sec_type = htobe((uint8_t)AuthNone);
        if (!write(&sec_cnt) || !write(&sec_type))
            return;
    }

    // Wait for client to respond
    curState = WaitForSecurityResponse;
}

void
VncServer::checkSecurity()
{
    assert(curState == WaitForSecurityResponse);

    uint8_t security_type;
    if (!read(&security_type))
        return;

    if (security_type != AuthNone) {
        warn("Unknown VNC security type\n");
        sendError("Unknown security type\n");
    }

    DPRINTF(VNC, "Sending security auth OK\n");

    uint32_t success = htobe(VncOK);
    if (!write(&success))
        return;
    curState = WaitForClientInit;
}

void
VncServer::sendServerInit()
{
    ServerInitMsg msg;

    DPRINTF(VNC, "Sending server init message to client\n");

    msg.fbWidth = htobe(videoWidth());
    msg.fbHeight = htobe(videoHeight());

    msg.px.bpp = htobe(pixelFormat.bpp);
    msg.px.depth = htobe(pixelFormat.depth);
    msg.px.bigendian = htobe(pixelFormat.bigendian);
    msg.px.truecolor = htobe(pixelFormat.truecolor);
    msg.px.redmax = htobe(pixelFormat.redmax);
    msg.px.greenmax = htobe(pixelFormat.greenmax);
    msg.px.bluemax = htobe(pixelFormat.bluemax);
    msg.px.redshift = htobe(pixelFormat.redshift);
    msg.px.greenshift = htobe(pixelFormat.greenshift);
    msg.px.blueshift = htobe(pixelFormat.blueshift);
    memset(msg.px.padding, 0, 3);
    msg.namelen = 2;
    msg.namelen = htobe(msg.namelen);
    std::memcpy(msg.name, "M5", 2);

    if (!write(&msg))
        return;
    curState = NormalPhase;
}

void
VncServer::setPixelFormat()
{
    DPRINTF(VNC, "Received pixel format from client message\n");

    PixelFormatMessage pfm;
    if (!read1((uint8_t *)&pfm, sizeof(PixelFormatMessage)))
        return;

    DPRINTF(VNC, " -- bpp = %d; depth = %d; be = %d\n", pfm.px.bpp,
            pfm.px.depth, pfm.px.bigendian);
    DPRINTF(VNC, " -- true color = %d red,green,blue max = %d,%d,%d\n",
            pfm.px.truecolor, betoh(pfm.px.redmax), betoh(pfm.px.greenmax),
                betoh(pfm.px.bluemax));
    DPRINTF(VNC, " -- red,green,blue shift = %d,%d,%d\n", pfm.px.redshift,
            pfm.px.greenshift, pfm.px.blueshift);

    if (betoh(pfm.px.bpp) != pixelFormat.bpp ||
        betoh(pfm.px.depth) != pixelFormat.depth ||
        betoh(pfm.px.bigendian) != pixelFormat.bigendian ||
        betoh(pfm.px.truecolor) != pixelFormat.truecolor ||
        betoh(pfm.px.redmax) != pixelFormat.redmax ||
        betoh(pfm.px.greenmax) != pixelFormat.greenmax ||
        betoh(pfm.px.bluemax) != pixelFormat.bluemax ||
        betoh(pfm.px.redshift) != pixelFormat.redshift ||
        betoh(pfm.px.greenshift) != pixelFormat.greenshift ||
        betoh(pfm.px.blueshift) != pixelFormat.blueshift) {
        warn("VNC client doesn't support true color raw encoding\n");
        detach();
    }
}

void
VncServer::setEncodings()
{
    DPRINTF(VNC, "Received supported encodings from client\n");

    PixelEncodingsMessage pem;
    if (!read1((uint8_t *)&pem, sizeof(PixelEncodingsMessage)))
        return;

    pem.num_encodings = betoh(pem.num_encodings);

    DPRINTF(VNC, " -- %d encoding present\n", pem.num_encodings);
    supportsRawEnc = supportsResizeEnc = false;

    for (int x = 0; x < pem.num_encodings; x++) {
        int32_t encoding;
        if (!read(&encoding))
            return;
        DPRINTF(VNC, " -- supports %d\n", betoh(encoding));

        switch (betoh(encoding)) {
          case EncodingRaw:
            supportsRawEnc = true;
            break;
          case EncodingDesktopSize:
            supportsResizeEnc = true;
            break;
        }
    }

    if (!supportsRawEnc) {
        warn("VNC clients must always support raw encoding\n");
        detach();
    }
}

void
VncServer::requestFbUpdate()
{
    DPRINTF(VNC, "Received frame buffer update request from client\n");

    FrameBufferUpdateReq fbr;
    if (!read1((uint8_t *)&fbr, sizeof(FrameBufferUpdateReq)))
        return;

    fbr.x = betoh(fbr.x);
    fbr.y = betoh(fbr.y);
    fbr.width = betoh(fbr.width);
    fbr.height = betoh(fbr.height);

    DPRINTF(VNC, " -- x = %d y = %d w = %d h = %d\n", fbr.x, fbr.y, fbr.width,
            fbr.height);

    sendFrameBufferUpdate();
}

void
VncServer::recvKeyboardInput()
{
    DPRINTF(VNC, "Received keyboard input from client\n");
    KeyEventMessage kem;
    if (!read1((uint8_t *)&kem, sizeof(KeyEventMessage)))
        return;

    kem.key = betoh(kem.key);
    DPRINTF(VNC, " -- received key code %d (%s)\n", kem.key, kem.down_flag ?
            "down" : "up");

    if (keyboard)
        keyboard->keyPress(kem.key, kem.down_flag);
}

void
VncServer::recvPointerInput()
{
    DPRINTF(VNC, "Received pointer input from client\n");
    PointerEventMessage pem;

    if (!read1((uint8_t *)&pem, sizeof(PointerEventMessage)))
        return;

    pem.x = betoh(pem.x);
    pem.y = betoh(pem.y);
    DPRINTF(VNC, " -- pointer at x = %d y = %d buttons = %#x\n", pem.x, pem.y,
            pem.button_mask);

    if (mouse)
        mouse->mouseAt(pem.x, pem.y, pem.button_mask);
}

void
VncServer::recvCutText()
{
    DPRINTF(VNC, "Received client copy buffer message\n");

    ClientCutTextMessage cct;
    if (!read1((uint8_t *)&cct, sizeof(ClientCutTextMessage)))
        return;

    char str[1025];
    size_t data_len = betoh(cct.length);
    DPRINTF(VNC, "String length %d\n", data_len);
    while (data_len > 0) {
        size_t bytes_to_read = data_len > 1024 ? 1024 : data_len;
        if (!read((uint8_t *)&str, bytes_to_read))
            return;
        str[bytes_to_read] = 0;
        data_len -= bytes_to_read;
        DPRINTF(VNC, "Buffer: %s\n", str);
    }

}


void
VncServer::sendFrameBufferUpdate()
{

    if (dataFd <= 0 || curState != NormalPhase || !sendUpdate) {
        DPRINTF(VNC, "NOT sending framebuffer update\n");
        return;
    }

    // The client will request data constantly, unless we throttle it
    sendUpdate = false;

    DPRINTF(VNC, "Sending framebuffer update\n");

    FrameBufferUpdate fbu;
    FrameBufferRect fbr;

    fbu.type = ServerFrameBufferUpdate;
    fbu.num_rects = 1;
    fbr.x = 0;
    fbr.y = 0;
    fbr.width = videoWidth();
    fbr.height = videoHeight();
    fbr.encoding = EncodingRaw;

    // fix up endian
    fbu.num_rects = htobe(fbu.num_rects);
    fbr.x = htobe(fbr.x);
    fbr.y = htobe(fbr.y);
    fbr.width = htobe(fbr.width);
    fbr.height = htobe(fbr.height);
    fbr.encoding = htobe(fbr.encoding);

    // send headers to client
    if (!write(&fbu) || !write(&fbr))
        return;

    assert(fb);

    std::vector<uint8_t> line_buffer(pixelConverter.length * fb->width());
    for (int y = 0; y < fb->height(); ++y) {
        // Convert and send a line at a time
        uint8_t *raw_pixel(line_buffer.data());
        for (unsigned x = 0; x < fb->width(); ++x) {
            pixelConverter.fromPixel(raw_pixel, fb->pixel(x, y));
            raw_pixel += pixelConverter.length;
        }

        if (!write(line_buffer.data(), line_buffer.size()))
            return;
    }
}

void
VncServer::sendFrameBufferResized()
{
    assert(fb && dataFd > 0 && curState == NormalPhase);
    DPRINTF(VNC, "Sending framebuffer resize\n");

    FrameBufferUpdate fbu;
    FrameBufferRect fbr;

    fbu.type = ServerFrameBufferUpdate;
    fbu.num_rects = 1;
    fbr.x = 0;
    fbr.y = 0;
    fbr.width = videoWidth();
    fbr.height = videoHeight();
    fbr.encoding = EncodingDesktopSize;

    // fix up endian
    fbu.num_rects = htobe(fbu.num_rects);
    fbr.x = htobe(fbr.x);
    fbr.y = htobe(fbr.y);
    fbr.width = htobe(fbr.width);
    fbr.height = htobe(fbr.height);
    fbr.encoding = htobe(fbr.encoding);

    // send headers to client
    if (!write(&fbu))
        return;
    write(&fbr);

    // No actual data is sent in this message
}

void
VncServer::setDirty()
{
    VncInput::setDirty();

    sendUpdate = true;
    sendFrameBufferUpdate();
}

void
VncServer::frameBufferResized()
{
    if (dataFd > 0 && curState == NormalPhase) {
        if (supportsResizeEnc)
            sendFrameBufferResized();
        else
            // The frame buffer changed size and we can't update the client
            detach();
    }
}
