/***********************************************************************
 * 
 *  Copyright (C) 2006 Novell, Inc. All Rights Reserved.
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; version 2.1
 *  of the License.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Library Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, Novell, Inc.
 * 
 *  To contact Novell about this file by physical or electronic mail, 
 *  you may find current contact information at www.novell.com.
 * 
 *  Author: Juan Carlos Luciani <jluciani@novell.com>
 *
 ***********************************************************************/

#include <windows.h>
#include "casa_auth_token.h"

int main(int argc, char* argv[])
{
   int   retStatus;
   char  authToken[4096];
   int   authTokenLen = sizeof(authToken);

   // Now lets obtain a token for our service
   retStatus = ObtainAuthToken("testService@137.65.132.44", authToken, &authTokenLen);
   if (retStatus)
      printf("ObtainAuthToken failed with status %d\n", retStatus);
   else
   {
      char                 serverAddr[] = "137.65.132.44";
      char                 *pServerAddress = serverAddr;
      int                  serverPort = 4444;
      SOCKET               sock;
      struct sockaddr_in   localAddr = {0};
      struct sockaddr_in   remoteAddr = {0};
      struct linger        linger_opt = {1, 15};
      struct hostent       *pLookupResult;
      int                  winsockStartupResult;
      WSADATA              winsockData;

      //printf("ObtainAuthToken succedded, token = %s\n", authToken);
      printf("ObtainAuthToken succedded, tokenlen = %d\n", authTokenLen);

      // Send the token to the server
      //
      // First initialize winsock
      if ((winsockStartupResult = WSAStartup(MAKEWORD(2,2), &winsockData)) == 0)
      {
         // Open socket
         sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
         if (sock != INVALID_SOCKET)
         {
            // Setup the local address structure
            localAddr.sin_family = AF_INET;
            localAddr.sin_addr.s_addr = htonl(INADDR_ANY);

            // Bind socket
            if (!bind(sock, (const struct sockaddr*) &localAddr, sizeof(struct sockaddr_in)))
            {
               // Resolve the server address
               pLookupResult = gethostbyname(pServerAddress);
               if (pLookupResult)
               {
                  // Validate the address type returned
                  if (pLookupResult->h_addrtype == AF_INET)
                  {
                     int   numAddressesFound = 0;

                     // Determine how many addresses where returned
                     while (pLookupResult->h_addr_list[numAddressesFound] != NULL)
                     {
                        //printf("ServerAddress = %08X\n", *((int*) pLookupResult->h_addr_list[numAddressesFound]));
                        numAddressesFound ++;
                     }
                     //printf("Found %d addresses\n", numAddressesFound);


                     // Setup the remote address structure with the lookup results
                     remoteAddr.sin_family = AF_INET;
                     remoteAddr.sin_port = htons(serverPort);
                     remoteAddr.sin_addr.s_addr = *((int*) pLookupResult->h_addr_list[0]); // Short-cut
                     //printf("ServerAddress = %08X\n", remoteAddr.sin_addr.s_addr);

                     // Perform connect operation
                     if (connect(sock,
                                 (struct sockaddr*) &remoteAddr,
                                 sizeof(struct sockaddr_in)) == SOCKET_ERROR)
                     {
                        printf("main()- Connection creation failed, error = %d\n", WSAGetLastError());
                     }
                     else
                     {
                        // Now the connection is setup, send the credentials to the server as one line.
                        // using our cheesy protocol followed by a hello string.

                        // Send the username to the server (including NULL terminator)
                        //send(sock, userName, userNameBufLen, 0);

                        // Send new line
                        //send(sock, "\n", 1, MSG_NOSIGNAL);

                        // Send the token to the server (including NULL terminator)
                        send(sock, authToken, (int) strlen(authToken) + 1, 0);

                        // Send new line
                        //send(sock, "\n", 1, 0);

                        // Send "hello"
                        //send(sock, helloString, strlen(helloString) + 1, MSG_NOSIGNAL);

                        // Send new line
                        //send(sock, "\n", 1, 0);

                        // Shutdown the connection
                        shutdown(sock, 0);
                     }
                  }
                  else
                  {
                     printf("main()- Unsupported address type returned %08X\n", pLookupResult->h_addrtype);
                  }
               }
               else
               {
                  printf("main()- Lookup for %s failed\n", pServerAddress);
               }
            }
            else
            {
               printf("main()- Unable to bind socket, error = %d", errno);
            }

            // Close the socket
            setsockopt(sock, SOL_SOCKET, SO_LINGER, (const char*) &linger_opt, sizeof(linger_opt));
            closesocket(sock);
         }
         else
         {
            printf("main()- Unable to open socket, error = %d\n", errno);
         }

         // Close winsock
         WSACleanup();
      }
      else
      {
         printf("main()- WSAStartup failed, error = %d\n", winsockStartupResult);
      }
   }

   printf("Enter to exit application\n");
   getchar();
   return 0;
}