/**********************************************************************
 *
 * extlinkaction.cpp -- 
 * Copyright (C) 1999  The New Zealand Digital Library Project
 *
 * A component of the Greenstone digital library software
 * from the New Zealand Digital Library Project at the
 * University of Waikato, New Zealand.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *********************************************************************/

#include "gsdl_modules_cfg.h"
#ifdef GSDL_USE_EXTLINK_ACTION

#include <string.h>
#include "extlinkaction.h"
#include "recptprototools.h"
#include "cgiutils.h"

extlinkaction::extlinkaction () {

  // this action uses cgi variables "a", "d", and "href"

  cgiarginfo arg_ainfo;
  arg_ainfo.shortname = "a";
  arg_ainfo.longname = "action";
  arg_ainfo.multiplechar = true;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::weak;
  arg_ainfo.argdefault = "extlink";
  arg_ainfo.savedarginfo = cgiarginfo::must;
  argsinfo.addarginfo (NULL, arg_ainfo);

  arg_ainfo.shortname = "el";
  arg_ainfo.longname = "external link preference";
  arg_ainfo.multiplechar = true;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::weak;
  arg_ainfo.argdefault = "direct"; // changed from "prompt" - will now directly load external links instead of
                                   // going through an intermediate page indicating that the link is external
  arg_ainfo.savedarginfo = cgiarginfo::must;
  argsinfo.addarginfo (NULL, arg_ainfo);

  arg_ainfo.shortname = "d";
  arg_ainfo.longname = "document OID";
  arg_ainfo.multiplechar = true;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::none;
  arg_ainfo.argdefault = g_EmptyText;
  arg_ainfo.savedarginfo = cgiarginfo::can;
  argsinfo.addarginfo (NULL, arg_ainfo);

  arg_ainfo.shortname = "href";
  arg_ainfo.longname = "URL of external link";
  arg_ainfo.multiplechar = true;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::none;
  arg_ainfo.argdefault = g_EmptyText;
  arg_ainfo.savedarginfo = cgiarginfo::can;
  argsinfo.addarginfo (NULL, arg_ainfo);

  arg_ainfo.shortname = "rl";
  arg_ainfo.longname = "is relative link";
  arg_ainfo.multiplechar = false;
  arg_ainfo.multiplevalue = false;
  arg_ainfo.defaultstatus = cgiarginfo::none;
  arg_ainfo.argdefault = "0";
  arg_ainfo.savedarginfo = cgiarginfo::mustnot;
  argsinfo.addarginfo (NULL, arg_ainfo);

}

extlinkaction::~extlinkaction () {
}


void extlinkaction::get_cgihead_info (cgiargsclass &args, recptprotolistclass *protos,
				      response_t &response, text_t &response_data, 
				      ostream &logout) {

  text_t link;
  if (get_link (args, protos, link, logout)) {
    response = location;
    response_data = link;
    return;
  }

  // external link
  if (!link.empty()) {
    if (args["el"] == "direct") {
      response = location;
      response_data = link;
      return;
    }
  }

  response = content;
  response_data = "text/html";
}

void extlinkaction::define_internal_macros (displayclass &disp, cgiargsclass &args, 
					    recptprotolistclass * /*protos*/, 
					    ostream &/*logout*/) {
  
  // define_internal_macros sets the following macros:

  // _nexturl_             link to external page
  // _prevdoc_             link to previous document
  //  disp.setmacro("nexturl", "extlink", cgi_safe(args["href"]));
  // problem in whist, above line changed.  Perhaps decode_cgi_arg ??
  // see also HTML plugin

  text_t nexturl_macro = args["href"];
  if(!isValidURLProtocol(nexturl_macro)) {
    nexturl_macro = encodeForURL(nexturl_macro); // URL has invalid protocol like javascript:, so URL encode it
  } else {
    nexturl_macro = encodeForHTMLAttr(nexturl_macro);
  }

  disp.setmacro("nexturl", "extlink", nexturl_macro); // goes into a full-url context
  disp.setmacro("prevdoc", "extlink", args["d"]);
}


// if link is found returns true and url in link, otherwise returns
// false
bool extlinkaction::get_link (cgiargsclass &args, recptprotolistclass *protos,
			      text_t &link, ostream &logout) {

    text_t &arg_href = args["href"];
    text_t &thiscollection = args["c"];
    if (arg_href.empty()) return false;

    text_t httpdoc = "_gwcgi_?e=_compressedoptions_&a=d";
    if (args["rl"] == "1") {

      FilterResponse_t response;
      text_tset metadata;
      metadata.insert ("section");
	  
      recptproto *collectproto = protos->getrecptproto (thiscollection, logout);

      if (get_info (arg_href, thiscollection, args["l"], metadata, false, collectproto, response, logout)) {
	if (!response.docInfo[0].metadata["section"].values[0].empty()) {
	  link = httpdoc+"&d=" + response.docInfo[0].metadata["section"].values[0];
	  return true;
	}
      }

      // need to see if link exists in any other collection
      // if cross-collection searching/browsing is turned on 
      if (args["ccs"] == "1" && !args["cc"].empty()) {
	text_tarray collections;
	splitchar (args["cc"].begin(), args["cc"].end(), ',', collections);

	text_tarray::const_iterator col_here = collections.begin();
	text_tarray::const_iterator col_end = collections.end();

	while (col_here != col_end) {
	  
	  // don't need to check current collection again
	  if (*col_here == thiscollection) {++col_here; continue;}
	  
	  recptproto *collectproto = protos->getrecptproto (*col_here, logout);
	  if (collectproto == NULL) {++col_here; continue;}

	  if (get_info (arg_href, *col_here, args["l"], metadata, false, collectproto, response, logout)) {
	    if (!response.docInfo[0].metadata["section"].values[0].empty()) {
	      link = httpdoc+"&c=" + *col_here + "&d=" +
		response.docInfo[0].metadata["section"].values[0];
	      return true;
	    }
	  }
	  ++col_here;
	}
      }
      return false;
      
    } else {
      // link is external 
      link = arg_href;
      return false;
    }
}


bool extlinkaction::do_action (cgiargsclass &args, recptprotolistclass *protos, 
			       browsermapclass * /*browsers*/, displayclass &disp,
			       outconvertclass &outconvert, ostream &textout,
			       ostream &logout) {
 
  if (args["href"].empty()) {
     // oops, this shouldn't happen
    textout << outconvert << disp << ("_extlink:header_\n")
	    << ("_extlink:notfoundcontent_\n")
	    << ("_extlink:footer_\n");
    return true;
  }

  if (args["rl"] == "1") {
    // need to see if link exists in any other collection
    // if cross-collection searching/browsing is turned on 
    if (args["ccs"] == "1" && !args["cc"].empty()) {
      
      FilterResponse_t response;
      text_tset metadata;
      metadata.insert ("section");
      text_tarray collections;
      splitchar (args["cc"].begin(), args["cc"].end(), ',', collections);
      
      text_tarray::const_iterator col_here = collections.begin();
      text_tarray::const_iterator col_end = collections.end();
      
      while (col_here != col_end) {
	
	// don't need to check current collection
	if (*col_here == args["c"]) {++col_here; continue;}
	
	recptproto *collectproto = protos->getrecptproto (*col_here, logout);
	if (get_info (args["href"], *col_here, args["l"], metadata, false, collectproto, response, logout)) {
	  if (!response.docInfo[0].metadata["section"].values[0].empty()) {
	    ColInfoResponse_t *cinfo = recpt->get_collectinfo_ptr (collectproto, *col_here, logout);
	    text_t collectionname = cinfo->get_collectionmeta("collectionname", args["l"]); //
	    if (collectionname.empty()) {
	      collectionname = *col_here;
	    }
	    textout << outconvert << disp << ("_extlink:header_\n")
		    << ("_extlink:foundintcontent_(" + *col_here + ", " + collectionname + 
			", " + response.docInfo[0].metadata["section"].values[0] + "\n")
		    << ("_extlink:footer_\n");
	    return true;
	  }
	}
	++col_here;
      }
    }
    textout << outconvert << disp << ("_extlink:header_\n")
	    << ("_extlink:notfoundcontent_\n")
	    << ("_extlink:footer_\n");
    
    
  } else {
    // link is external 
    textout << outconvert << disp << ("_extlink:header_\n")
	    << ("_extlink:foundcontent_\n")
	    << ("_extlink:footer_\n");
  }

  return true;
}

#endif //GSDL_USE_EXTLINK_ACTION
