//---------------------------------------------------------------------------
//
// MODULE NAME:     main.cpp
//
// COPYRIGHT:       Copyright (c) 2013, GladeSoft, Inc.
//                  All Rights Reserved.
//
//                  NOTICE: THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF
//                  GLADESOFT, INC., AND SHALL NOT BE REPRODUCED, COPIED
//                  IN WHOLE OR IN PART ADAPTED, MODIFIED, OR
//                  DISSEMINATED WITHOUT THE EXPRESS WRITTEN CONSENT
//                  OF GLADESOFT, INC. ANY REDISTRIBUTION OR
//                  PUBLICATION TO UNAUTHORIZED PERSONS IS STRICTLY
//                  PROHIBITED BY U.S. AND INTERNATIONAL COPYRIGHT LAW.
//
// DESCRIPTION:     HTTP Client example (POST with a body)
//
// AUTHOR:          M. Grosberg
//
// CREATION DATE:   Jun 18, 2009
//
//---------------------------------------------------------------------------
//
// HISTORY OF CHANGE  
//
// -----+--------+------------------------------------------+------+---------
// VERS | DATE   | DESCRIPTION OF CHANGE                    | INIT | PR#
// =====+========+==========================================+======+=========
//  001 |06/18/09| File creation.                           | MYG  |
// -----+--------+------------------------------------------+------+---------
// -----+--------+------------------------------------------+------+---------
//---------------------------------------------------------------------------

#include "sem_client.h"

/*
 * This class is a bridge that wraps STDOUT in the HttpdWritable interface.
 */
class StdOut : public HttpdWritable
{
public:
  virtual int Write(size_t n, const void *p_body);
};

int StdOut::Write(size_t n, const void *p_body)
{
  printf("%-*.*s", (int )n, (int )n, (const char *)p_body);
  return 0;
}

static StdOut gStdout;

/*
 * This class extends a fetch so that the response body is sent to STDOUT.
 */
class FetchTest : public HttpdClientFetch
{
protected:
  virtual int ResponseOk(HttpdClientTransfer &xfer, HttpdOutboundTransfer &body);
 
public:
  FetchTest(HttpdClient &client) : HttpdClientFetch(client) {}
};

int FetchTest::ResponseOk(HttpdClientTransfer &xfer, HttpdOutboundTransfer &body)
{
  return (body.Receiver()->Pump(&gStdout, HTTPD_CGI_TIMEOUT));
}

static const char request_body[] = "param1=yes&param2=no&more=data";

int main(int argc, const char **argv)
{
  int rc;

  rc = Httpd::Init();
  if (rc != 0)
  {
    printf("Can't init the system-level stack rc=%d.\n", rc);
    return (EXIT_FAILURE);
  }

  // Create an object that exposes the request body. In this case 
  // the request body is a staic buffer so use the built-in wrapper
  // class.
  HttpdClientBufferRequestBody  rb(request_body, sizeof(request_body) - 1);
  HttpdClient                   client;
  HttpdClientKeyRing            keyring(64, 3600);

  rc = client.Create();
  if (rc != 0)
  {
    printf("Can't create client. rc=%d\n", rc);
    return (EXIT_FAILURE);
  }

  rc = keyring.Create();
  if (rc != 0)
  {
    printf("Can't create keyring. rc=%d\n", rc);
    return (EXIT_FAILURE);
  }

  client.SetKeyRing(&keyring);

  const char *p_url;
  if (argc >= 2)
    p_url = argv[1];
  else
    p_url = "http://gladesoft.com:8080/cgiparams.thtm";

  FetchTest req(client);
  req.BodySource(&rb);
  req.BodyContentType("application/x-www-form-urlencoded");
  rc = req.Fetch(p_url, HttpdUtilities::mPostRequest);
  if (rc != 0)
  {
    printf("--------------------------------------------------------\n");
    printf("Fetch of %s failed. rc=%d\n", p_url, rc);
    printf("--------------------------------------------------------\n");

    return (EXIT_FAILURE);
  }

  printf("Done.\n");
  return (EXIT_SUCCESS);
}

