/*
 * Copyright (c) 2015 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h> 

#define SOCKCLNT_SERVER_PORT 32741 /* whatever */

typedef signed char i8;
typedef signed short i16;
typedef signed int i32;
typedef signed long long i64;
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef unsigned long uword;

#define VL_API_PACKED(x) x __attribute__ ((packed))

typedef VL_API_PACKED(struct _vl_api_sockclnt_create {
    u16 _vl_msg_id;
    u8 name[64];
    u32 context;
}) vl_api_sockclnt_create_t;

typedef VL_API_PACKED(struct _vl_api_sockclnt_create_reply {
    u16 _vl_msg_id;
    i32 response;
    u64 handle;
    u32 index;
    u32 context;
}) vl_api_sockclnt_create_reply_t;

typedef VL_API_PACKED(struct _vl_api_sockclnt_delete {
    u16 _vl_msg_id;
    u32 index;
    u64 handle;
}) vl_api_sockclnt_delete_t;

typedef VL_API_PACKED(struct _vl_api_sockclnt_delete_reply {
    u16 _vl_msg_id;
    i32 response;
    u64 handle;
}) vl_api_sockclnt_delete_reply_t;

void error(char *msg)
{
    perror(msg);
    exit(0);
}

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;
    char buffer[256];
    int i;
    u32 nbytes;
    vl_api_sockclnt_create_t *mp;
    vl_api_sockclnt_create_reply_t *rp;
    char *rdptr;
    int total_bytes;

    for (i = 0; i < 1; i++) {
        portno = SOCKCLNT_SERVER_PORT;
        sockfd = socket(AF_INET, SOCK_STREAM, 0);
        if (sockfd < 0) 
            error("ERROR opening socket");
        server = gethostbyname("localhost");
        if (server == NULL) {
            fprintf(stderr,"ERROR, no such host\n");
            exit(0);
        }
        bzero((char *) &serv_addr, sizeof(serv_addr));
        serv_addr.sin_family = AF_INET;
        bcopy((char *)server->h_addr, 
              (char *)&serv_addr.sin_addr.s_addr,
              server->h_length);
        serv_addr.sin_port = htons(portno);
        if (connect(sockfd,(const void *)&serv_addr,sizeof(serv_addr)) < 0) 
            error("ERROR connecting");

        memset(buffer, 0, sizeof(buffer));

        mp = (vl_api_sockclnt_create_t *)buffer;
        mp->_vl_msg_id = ntohs(8); /* VL_API_SOCKCLNT_CREATE */
        strncpy ((char *) mp->name, "socket-test", sizeof(mp->name)-1);
        mp->name[sizeof(mp->name)-1]=0;
        mp->context = 0xfeedface;
        /* length of the message, including the length itself */
        nbytes = sizeof (*mp) + sizeof (nbytes);
        nbytes = ntohl(nbytes);
        n = write(sockfd, &nbytes, sizeof(nbytes));
        if (n < 0) 
            error("ERROR writing len to socket");
        n = write(sockfd, mp, sizeof (*mp));
        if (n < 0) 
            error("ERROR writing msg to socket");

        memset(buffer, 0, sizeof (buffer));

        total_bytes = 0;
        rdptr = buffer;
        do {
            n = read(sockfd,rdptr,sizeof(buffer) - (rdptr - buffer));
            if (n < 0) 
                error("ERROR reading from socket");
            printf ("read %d bytes\n", n);
            total_bytes += n;
            rdptr += n;
        } while (total_bytes < sizeof (vl_api_sockclnt_create_reply_t) + 4);

        rp = (vl_api_sockclnt_create_reply_t *)(buffer + 4);
        /* VL_API_SOCKCLNT_CREATE_REPLY */
        if (ntohs(rp->_vl_msg_id) != 9) {
            printf ("WARNING: msg id %d\n", ntohs(rp->_vl_msg_id));
        }

        printf ("response %d, handle 0x%llx, index %d, context 0x%x\n",
                ntohl(rp->response), rp->handle, rp->index, rp->context);
        close(sockfd);
    }
    return 0;
}
