#include "nanomsg/src/nn.h"
#include "nanomsg/src/pipeline.h"
#include "nanomsg/src/reqrep.h"

#include "SkCanvas.h"
#include "SkCommandLineFlags.h"
#include "SkData.h"
#include "SkForceLinking.h"
#include "SkGraphics.h"
#include "SkImageEncoder.h"
#include "SkOSFile.h"
#include "SkPicture.h"
#include "SkRandom.h"
#include "SkStream.h"

__SK_FORCE_IMAGE_DECODER_LINKING;

// To keep things simple, PictureHeader is fixed-size POD.
struct PictureHeader {
    SkMatrix         matrix;
    SkRect           clip;
    SkXfermode::Mode xfermode;
    pid_t            pid;
    uint8_t          alpha;

    PictureHeader()
        : matrix(SkMatrix::I())
        , clip(SkRect::MakeLargest())
        , xfermode(SkXfermode::kSrcOver_Mode)
        , pid(getpid())
        , alpha(0xFF) {}
};

// A little adaptor: nn_iovec wants a non-const pointer for no obvious reason.
static struct nn_iovec create_iov(const void* ptr, size_t size) {
    struct nn_iovec iov = { const_cast<void*>(ptr), size };
    return iov;
}

static void send_picture(int socket, const PictureHeader& header, const SkData& skp) {
    // Vectored IO lets us send header and skp contiguously without first
    // copying them to a contiguous buffer.
    struct nn_iovec iov[] = {
        create_iov(&header, sizeof(header)),
        create_iov(skp.data(), skp.size()),
    };

    struct nn_msghdr msg;
    sk_bzero(&msg, sizeof(msg));
    msg.msg_iov    = iov;
    msg.msg_iovlen = SK_ARRAY_COUNT(iov);

    nn_sendmsg(socket, &msg, 0/*flags*/);
}

static SkPicture* recv_picture(int socket, PictureHeader* header) {
    static const size_t hSize = sizeof(*header);  // It's easy to slip up and use sizeof(header).

    void* msg;
    int size = nn_recv(socket, &msg, NN_MSG, 0/*flags*/);
    SkDebugf("%d bytes", size);

    // msg is first a fixed-size header, then an .skp.
    memcpy(header, msg, hSize);
    SkMemoryStream stream((uint8_t*)msg + hSize, size - hSize);
    SkPicture* pic = SkPicture::CreateFromStream(&stream);

    SkDebugf(" from proccess %d:", header->pid);

    nn_freemsg(msg);
    return pic;
}

static void client(const char* skpPath, const char* dataEndpoint) {
    // Read the .skp.
    SkAutoTUnref<const SkData> skp(SkData::NewFromFileName(skpPath));
    if (!skp) {
        SkDebugf("Couldn't read %s\n", skpPath);
        exit(1);
    }
    SkMemoryStream stream(skp->data(), skp->size());
    SkAutoTUnref<SkPicture> picture(SkPicture::CreateFromStream(&stream));

    PictureHeader header;
    SkRandom rand(picture->cullRect().width() * picture->cullRect().height());
    SkScalar r = rand.nextRangeScalar(0, picture->cullRect().width()),
             b = rand.nextRangeScalar(0, picture->cullRect().height()),
             l = rand.nextRangeScalar(0, r),
             t = rand.nextRangeScalar(0, b);
    header.clip.setLTRB(l,t,r,b);
    header.matrix.setTranslate(-l, -t);
    header.matrix.postRotate(rand.nextRangeScalar(-25, 25));
    header.alpha = 0x7F;

    //Clients use NN_REQ (request) type sockets.
    int socket = nn_socket(AF_SP, NN_REQ);

    // Clients connect a socket to an endpoint.
    nn_connect(socket, dataEndpoint);

    // Send the picture and its header.
    SkDebugf("Sending %s (%d bytes)...", skpPath, skp->size());
    send_picture(socket, header, *skp);

    // Wait for ack.
    uint8_t ack;
    nn_recv(socket, &ack, sizeof(ack), 0/*flags*/);
    SkDebugf(" ok.\n");
}

// Wait until socketA or socketB has something to tell us, and return which one.
static int poll_in(int socketA, int socketB) {
    struct nn_pollfd polls[] = {
        { socketA, NN_POLLIN, 0 },
        { socketB, NN_POLLIN, 0 },
    };

    nn_poll(polls, SK_ARRAY_COUNT(polls), -1/*no timeout*/);

    if (polls[0].revents & NN_POLLIN) { return socketA; }
    if (polls[1].revents & NN_POLLIN) { return socketB; }

    SkFAIL("unreachable");
    return 0;
}

static void server(const char* dataEndpoint, const char* controlEndpoint, SkCanvas* canvas) {
    // NN_REP sockets receive a request then make a reply.  NN_PULL sockets just receive a request.
    int data    = nn_socket(AF_SP, NN_REP);
    int control = nn_socket(AF_SP, NN_PULL);

    // Servers bind a socket to an endpoint.
    nn_bind(data,    dataEndpoint);
    nn_bind(control, controlEndpoint);

    while (true) {
        int ready = poll_in(data, control);

        // If we got any message on the control socket, we can stop.
        if (ready == control) {
            break;
        }

        // We should have an .skp waiting for us on data socket.
        PictureHeader header;
        SkAutoTUnref<SkPicture> picture(recv_picture(data, &header));

        SkPaint paint;
        paint.setAlpha(header.alpha);
        paint.setXfermodeMode(header.xfermode);

        canvas->saveLayer(NULL, &paint);
            canvas->concat(header.matrix);
            canvas->clipRect(header.clip);
            picture->playback(canvas);
        canvas->restore();
        SkDebugf(" drew");

        // Send back an ack.
        uint8_t ack = 42;
        nn_send(data, &ack, sizeof(ack), 0/*flags*/);
        SkDebugf(" and acked.\n");
    }
}

static void stop(const char* controlEndpoint) {
    // An NN_PUSH socket can send messages but not receive them.
    int control = nn_socket(AF_SP, NN_PUSH);
    nn_connect(control, controlEndpoint);

    // Sending anything (including this 0-byte message) will tell server() to stop.
    nn_send(control, NULL, 0, 0/*flags*/);
}

DEFINE_string2(skp, r, "", ".skp to send (as client)");
DEFINE_string2(png, w, "", ".png to write (as server)");
DEFINE_bool(stop, false, "If true, tell server to stop and write its canvas out as a .png.");
DEFINE_string(data,    "ipc://nanomsg-picture-data",    "Endpoint for sending pictures.");
DEFINE_string(control, "ipc://nanomsg-picture-control", "Endpoint for control channel.");

int main(int argc, char** argv) {
    SkAutoGraphics ag;
    SkCommandLineFlags::Parse(argc, argv);

    if (FLAGS_stop) {
        stop(FLAGS_control[0]);
    }

    if (!FLAGS_skp.isEmpty()) {
        client(FLAGS_skp[0], FLAGS_data[0]);
    }

    if (!FLAGS_png.isEmpty()) {
        SkBitmap bitmap;
        bitmap.allocN32Pixels(1000, 1000);
        SkCanvas canvas(bitmap);
        canvas.clear(0xFFFFFFFF);

        server(FLAGS_data[0], FLAGS_control[0], &canvas);
        canvas.flush();

        SkImageEncoder::EncodeFile(FLAGS_png[0], bitmap, SkImageEncoder::kPNG_Type, 100);
        SkDebugf("Wrote %s.\n", FLAGS_png[0]);
    }

    return 0;
}
