/**********************************************************************
 *
 * identifyaction.cpp --
 *
 * Copyright (C) 2004-2010  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 "identifyaction.h"
#include "oaitools.h"

bool identifyaction::validateAction(recptproto *protocol, oaiargs &params)
{ 
  // ----------------------------------------------------------------------------
  //  1. Check for invalid arguments
  // ----------------------------------------------------------------------------
  bool invalid_argument_supplied = false;
  text_tmap::const_iterator param_iterator = params.begin();
  while (param_iterator != params.end())
  {
    // Check for arguments that aren't valid for this action
    if (param_iterator->first != "verb")
    {
      // We've found an invalid argument
      invalid_argument_supplied = true;

      // Delete the invalid argument from the list so it doesn't end up in the <request> tag that is returned
      params.erase(param_iterator->first);
    }

    param_iterator++;
  }

  // If we found an invalid argument it's an error, so don't go any further 
  if (invalid_argument_supplied)
  {
    this->errorType = "badArgument";
    return false;
  }

  // ----------------------------------------------------------------------------
  //  2. Handle any exclusive arguments
  // ----------------------------------------------------------------------------

  // None!

  // ----------------------------------------------------------------------------
  //  3. Handle any required arguments
  // ----------------------------------------------------------------------------

  // None!

  // ----------------------------------------------------------------------------
  // 4. Check any remaining arguments
  // ----------------------------------------------------------------------------

  // None!

  // If we've reached here everything must be fine
  this->errorType = "";
  return true;
}

bool identifyaction::output_content(ostream &output, recptproto *protocol, oaiargs &params)
{
  utf8outconvertclass utf8convert;

  // Get the repository name (some human-readable name for the site, or superset of collections)
  text_t repositoryName = this->configuration->getRepositoryName();
  text_t repositoryId = this->configuration->getRepositoryId();
  // Get admin's email address (i.e. the site maintainer)
  text_t maintainer = this->configuration->getMaintainer();
  text_t version = (this->configuration->getOAIVersion() <= 110) ? (text_t)"1.1":(text_t)"2.0";
  text_t id_version = this->configuration->getRepositoryIdVersion();
  
  text_t baseURL = this->configuration->getBaseURL();
  
  output << utf8convert << "  <repositoryName>"  << repositoryName << "</repositoryName>\n";
  output << utf8convert << "  <baseURL>"         << baseURL        << "</baseURL>\n";
  output << utf8convert << "  <protocolVersion>" << version        << "</protocolVersion>\n";
  output << utf8convert << "  <adminEmail>"      << maintainer     << "</adminEmail>\n";

  if(version == "2.0"){
    // earliestDatestamp *should* be the YYYY-MM-DD format of the oldest lastmodified record in the
    // repository, but we're just setting it to be the default oldest possible date - ugly, but judged
    // not to be worth the effort of trolling through all the lastmodified dates (by others with more 
    // say than me)
	
	// The above was before. However, now we mirror GS3 way of dealing with 
	// earliestDatestamp by going through the earliestDatestamp field of each OAI 
	// collection's build.cfg in order to work out earliestdatestamp of this Repository:
	// by going through all the collections and getting the earliest among the
	// "earliestDatestamp" values stored for each collection in its build.cfg
	// (the earliestDatestamp for a collection has already been extracted from 
	// their build.cfg file at this point by collectserver::configure. The field
	// is declared in comtypes.h) 	
	
	this->calcEarliestDatestamp(protocol, params);	// force the calculation. Sets mEarliestDatestamp member variable
	
    output << utf8convert << "  <earliestDatestamp>"<< this->mEarliestDatestamp <<"</earliestDatestamp>\n";
    output << utf8convert << "  <deletedRecord>persistent</deletedRecord>\n";
    output << utf8convert << "  <granularity>YYYY-MM-DD</granularity>\n";
  }
  // list the oai identifier
  output << "  <description>\n";
  if (id_version == "1.1") {

    output << "    <oai-identifier xmlns=\"http://www.openarchives.org/OAI/1.1/oai-identifier\"\n";
    output << "        xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
    output << "        xsi:schemaLocation=\"http://www.openarchives.org/OAI/1.1/oai-identifier\n";
    output << "           http://www.openarchives.org/OAI/1.1/oai-identifier.xsd\">\n";
  } else {

    output << "    <oai-identifier xmlns=\"http://www.openarchives.org/OAI/2.0/oai-identifier\"\n";
    output << "      xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
    output << "      xsi:schemaLocation=\"http://www.openarchives.org/OAI/2.0/oai-identifier\n";
    output << "        http://www.openarchives.org/OAI/2.0/oai-identifier.xsd\">\n";

    
  }

  output << "      <scheme>oai</scheme>\n";
  output << "      <repositoryIdentifier>"<< repositoryId <<"</repositoryIdentifier>\n";
  output << "      <delimiter>:</delimiter>\n";
  output << "      <sampleIdentifier>oai:"<<repositoryId<<":demo:HASH983080b052e9230b7ccf94</sampleIdentifier>\n";
  output << "    </oai-identifier>\n";

  // list all configuration information
  text_tmap::iterator here = this->configuration->getInformation()->begin();
  text_tmap::iterator end  = this->configuration->getInformation()->end();
  if (here != end) {
    output << "    <gsdl xmlns=\"http://www.greenstone.org/namespace/gsdl_oaiinfo/1.0/gsdl_oaiinfo\"\n";
    output << "       xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n";
    output << "       xsi:schemaLocation=\"http://www.greenstone.org/namespace/gsdl_oaiinfo/1.0/gsdl_oaiinfo\n";
    output << "         http://www.greenstone.org/namespace/gsdl_oaiinfo/1.0/gsdl_oaiinfo.xsd\">\n";
  

    while (here != end) {
      output << utf8convert << "      <Metadata name=\"" << here->first << "\">" << here->second << "</Metadata>\n";
      ++here;
    }
    output << "    </gsdl>\n";
  }
  
  output << utf8convert << "  </description>\n";
  
  return true;
}

