// ------------------------------- //
// -------- Start of File -------- //
// ------------------------------- //
// ----------------------------------------------------------- // 
// C++ Source Code File Name: testprog.cpp
// Compiler Used: MSVC, BCC32, GCC, HPUX aCC, SOLARIS CC
// Produced By: glNET Software
// File Creation Date: 01/25/2000
// Date Last Modified: 06/25/2001
// Copyright (c) 2001 glNET Software
// ----------------------------------------------------------- // 
// ------------- Program Description and Details ------------- // 
// ----------------------------------------------------------- // 
/*
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; either
version 2.1 of the License, or (at your option) any later version.
 
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
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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  
USA

This program is used to test the HTTP, HTML, and URL classes.
*/
// ----------------------------------------------------------- // 
#include <iostream.h>
#include "gxshttp.h"
#include "gxshttpc.h"
#include "httpgrab.h"
#include "dfileb.h"

#ifdef __MSVC_DEBUG__
#include "leaktest.h"
#endif

// Version number and program name
const double ProgramVersionNumber = 4000.101;
const char *ProgramName = "http testprog";

// Program globals
int get_doc_header = 0; // True if request a docment header only
int get_document = 0;   // True if requesting a document 

void HelpMessage(const char *program_name, const double version_number)
{
  cout << endl;
  cout.setf(ios::showpoint | ios::fixed);
  cout.precision(3);
  cout << endl;
  cout << program_name << " version " << version_number  << endl;
  cout << "Usage: " << program_name << " [switches] URL" << endl;
  cout << "Example: " << program_name << " -h http://www.xyz.com/index.html"
       << endl;
  cout << "Switches: " << endl;
  cout << "          -g = Grab the specified file only (default)." << endl;
  cout << "          -h = Get a document header." << endl;
  cout << endl;
}

int ProcessArgs(char *arg)
{
  switch(arg[1]) {
    case 'h':
      get_doc_header = 1;
      get_document = 0;
      break;

    case 'g':
      get_doc_header = 0;
      get_document = 1;
      break;
      
    default:
      cerr << endl;
      cerr << "Unknown switch " << arg << endl;
      cerr << "Exiting..." << endl;
      cerr << endl;
      return 0;
  }
  arg[0] = '\0';

  return 1; // All command line arguments were valid
}

void GetDocumentHeader(char *URL)
{
  gxsURL url;
  gxsURLInfo u;
  gxString web_url(URL);
  
  if(!url.ParseURL(web_url, u)) {
    cout << "Error parsing url" << endl;
    return;
  }

  gxsHTTPClient httpc;
  gxsHTTPHeader hdr;

  if(httpc.RequestHeader(u, hdr) != 0) {
    cout << httpc.SocketExceptionMessage() << endl;
    return;
  }

  hgPringHTTPHeader(hdr);
}

void DownloadFile(const char *URL)
{
  gxsHTTPClient client;
  gxsURL url;
  gxsURLInfo u;
  if(!url.ParseURL(URL, u)) {
    cout << "Error parsing URL" << endl;
  }

  // Construct the local file name based on the URL information
  gxString sbuf(u.dir);
  if(u.file == "?") { // Is this a file or directory
    while(sbuf.DeleteBeforeIncluding("/")) ;
    u.file = sbuf;
    u.dir.DeleteAfterIncluding(sbuf.c_str());
  }
  if(!u.file) {
    u.file = "index.html";
  }

  // Replace any unsafe characters from the local file name
  gxString fbuf(u.file);
#if defined (__DOS__) || defined (__WIN32__)
  fbuf.FilterString("?");
#endif
  

  DiskFileB outfile(fbuf.c_str(), DiskFileB::df_WRITEONLY,
		    DiskFileB::df_CREATE, DiskFileB::df_TRUNCATE);
  if(!outfile) {
    cout << outfile.DiskFileExceptionMessage() << endl;
    return;
  }
  
  cout << "Connecting to " << u.host << endl;
  cout << "Grabbing " << u.path << endl;

  gxsHTTPHeader hdr;
  if(client.RequestHeader(u, hdr) != 0) {
    cout << client.SocketExceptionMessage() << endl;
    return;
  }
    
  if(client.RequestFile(u, hdr, outfile.df_FileStream()) != 0) {
    cout << client.SocketExceptionMessage() << endl;
    return;
  }

  client.Flush();
}

// Program's main thread of execution.
// ----------------------------------------------------------- 
int main(int argc, char **argv)
{
#ifdef __MSVC_DEBUG__
  InitLeakTest();
#endif

  if(argc < 2) { 
    HelpMessage(ProgramName, ProgramVersionNumber);
    return 0;
  }
  
  // Process command ling arguments and files 
  int narg;
  char *arg = argv[narg = 1];
  while (narg < argc) {
    if (arg[0] != '\0') {
      if (arg[0] == '-') { // Look for command line arguments
	if(!ProcessArgs(arg)) return 0; // Exit if argument is not valid
      }
      else { 
	if(get_document) {
	  cout << endl;
	  cout << "Grabbing: " << arg << endl;
	  DownloadFile((const char *)arg);
	}
	else if(get_doc_header) {
	  cout << endl;
	  cout << "Requesting document header: " << arg << endl;
	  GetDocumentHeader(arg);
	}
	else { // Default if no argument is specifed
	  cout << endl;
	  cout << "Grabbing: " << arg << endl;
	  DownloadFile((const char *)arg);
	}
      }
      arg = argv[++narg];
    }
  }
  
  return 0;
}
// ----------------------------------------------------------- //
// ------------------------------- //
// --------- End of File --------- //
// ------------------------------- //