package com.k_int.pnds;

import java.io.File;
import java.io.FileInputStream;
import java.net.URI;
import java.net.URLEncoder;
import java.sql.*;
import java.util.Date;
import java.util.Properties;
import javax.xml.parsers.*;
import com.k_int.ia.data_upload.dto.*;
import com.k_int.ia.data_upload.ConfigPair;
import com.k_int.ia.data_upload.ConfigTypes;
import com.k_int.ia.data_upload.DataPublishController;
import com.k_int.ia.data_upload.ThreadedDataPublisher;
import com.k_int.ia.data_upload.UploadStatus;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.w3c.dom.*;
import org.xml.sax.InputSource;
import org.apache.xpath.*;
import org.apache.xpath.objects.*;
import org.apache.xml.utils.*;
import org.apache.xpath.CachedXPathAPI;

public class CollectBritainPublisher extends ThreadedDataPublisher{

 
  public static Log log = LogFactory.getLog(CollectBritainPublisher.class);
  static ConfigPair[] config_fields; //= new ArrayList();
  public static String XMLNS_DC = "http://purl.org/dc/elements/1.1/";

  private CachedXPathAPI xpath = null;

  static {
      config_fields = new ConfigPair[6];
      
      ConfigPair pair = new ConfigPair();
      pair.setFieldName("name");
      pair.setFieldType(ConfigTypes.TEXTFIELD);    
      config_fields[0]=pair;
     
      pair = new ConfigPair();
      pair.setFieldName("publishURL");
      pair.setFieldType(ConfigTypes.TEXTAREA);
      config_fields[1]=pair;
      
      pair = new ConfigPair();
      pair.setFieldName("sourceURL");
      pair.setFieldType(ConfigTypes.URL_SELECTION);
      config_fields[2]=pair;
   
      pair = new ConfigPair();
      pair.setFieldName("targetCollection");
      pair.setFieldType(ConfigTypes.TEXTFIELD);
      config_fields[3]=pair;
      
      pair = new ConfigPair();
      pair.setFieldName("publisherIdentity");
      pair.setFieldType(ConfigTypes.TEXTFIELD);
      config_fields[4]=pair;
      
      pair = new ConfigPair();
      pair.setFieldName("publisherCredentials");
      pair.setFieldType(ConfigTypes.PASSWORD);
      config_fields[5]=pair;   
  }
  
  protected static DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
  private String targetCollection = "CollectBritain";
  private String sourceURL="file://mediaExport_00001_05000.xml";
 
  private transient Connection conn = null;
  private transient PreparedStatement get_org_details_ps = null;

 
  /**public synchronized void beginUpload(DataPublishController controller) 
  {
    this.controller = controller;
    if (!running) 
    {
      running = true;
      setStatus(UploadStatus.BUSY); //$NON-NLS-1$
      new Thread(this).start();
    }
  }**/
  
  public CollectBritainPublisher() {
    xpath = new CachedXPathAPI();
  }

  public void run() 
  {
    log.debug("Starting run");

    try {
      dbf.setNamespaceAware(true);
      DocumentBuilder docBuilder = dbf.newDocumentBuilder();
      
      
      URI uri = new URI(sourceURL);
      File file = new File(uri);
      
      FileInputStream fis = new FileInputStream(file);
      
      InputSource source = new InputSource(fis);
      source.setEncoding("ISO-8859-1");
    
      System.err.println("Parse document "+sourceURL);
      
      
      
      //Document result_doc = docBuilder.parse(sourceURL);
      Document result_doc = docBuilder.parse(source);
      System.err.println("done Parse document, extract nodes");
      Element repository_node = result_doc.getDocumentElement();
      repository_node.setAttribute("xmlns:pndsdc","http://purl.org/mla/pnds/pndsdc/");
      NodeList nl = xpath.selectNodeList(repository_node,"//pndsdc:description",repository_node);
      String default_authority = "collectBritain";

      System.err.println("Got "+nl.getLength()+" items to process");

      long start_time = 0;
      com.k_int.ia.util.RollingAverageCalculator rac = new com.k_int.ia.util.RollingAverageCalculator(100);
      for ( int i=0; i<nl.getLength(); i++ ) {
        start_time = System.currentTimeMillis();

        Element n = (Element) nl.item(i); 

        Element pndsdc_description = n;
        String id = getChildNodeText(n,XMLNS_DC,"identifier");

        if ( id == null ) {
          throw new com.k_int.ia.data_upload.DataPublishException("Null identifier");
        }

        // Create a new resource object for each record from the xml file
        ResourceDTO result = new ResourceDTO();
        log.debug("Elapsed before xpath "+(System.currentTimeMillis()-start_time));

        // Populate fields in the new resource
        result.setTitle(getChildNodeText(pndsdc_description,XMLNS_DC,"title"));

        int newi = i + 1;
        System.err.println("Processing node "+newi+"/"+nl.getLength()+" with title: "+getChildNodeText(pndsdc_description,XMLNS_DC,"title"));

        result.setDescription(getChildNodeText(pndsdc_description,XMLNS_DC,"description"));
        result.setPublisher(getChildNodeText(pndsdc_description,XMLNS_DC,"publisher"));
        result.setLanguage(getChildNodeText(pndsdc_description,XMLNS_DC,"language"));
        result.setType(getChildNodeText(pndsdc_description,XMLNS_DC,"type"));
        result.setFormat(getChildNodeText(pndsdc_description,XMLNS_DC,"format"));
        result.setAudience(getChildNodeText(pndsdc_description,XMLNS_DC,"audience"));
        result.setIdentifier(getChildNodeText(pndsdc_description,XMLNS_DC,"identifier"));
        result.setRights(getChildNodeText(pndsdc_description,XMLNS_DC,"rights"));
        result.setAlternate_title(getChildNodeText(pndsdc_description,XMLNS_DC,"alternate_title"));
        result.setMedium(getChildNodeText(pndsdc_description,XMLNS_DC,"medium"));
        result.setHasFormat(getChildNodeText(pndsdc_description,XMLNS_DC,"hasFormat"));
        result.setLast_modified((new Date()).getTime());
        result.setDate_issued(null);

        // Type Processing 
        // Transform
        // http://www.collectbritain.co.uk/personalisation/object.cfm?uid=001ADD000000117U00001000
        // Into
        // http://www.collectbritain.com/mediastore/001/000/001ADD000000117U00001000%5BSVC1%5D.JPG
        String uid = id.substring((id.lastIndexOf('='))+1);
        String thumbnail = null;
        if ( uid.startsWith("020") || uid.startsWith("021") || uid.startsWith("025") ) {
          thumbnail = "http://www.collectbritain.com/images/gifs/sound_sq.gif";
        }
        else {
          thumbnail = "http://www.collectbritain.com/mediastore/"+
                              uid.substring(0,3)+"/"+
                              uid.substring(16,19)+"/"+
                              uid+"[THM1].GIF";
        }

        log.debug("uid: "+uid);
        log.debug("thumbnail: "+thumbnail);
        log.debug("Elapsed before xpath list processing "+(System.currentTimeMillis()-start_time));

        result.setThumbnail(thumbnail);

    	NodeList n2 = xpath.selectNodeList(pndsdc_description,"./dc:subject",pndsdc_description);
    	for ( int j=0; j<n2.getLength(); j++ ) {
              Element sub_node = (Element)n2.item(j);
    	  // String subj_str = getDataFromFile(sub_node,"./text()");
    	  String subj_str = sub_node.getTextContent();
    	  if ((subj_str != null) && (subj_str.length() > 0)) {
    	    String urlEnc = sub_node.getAttribute("encSchemeURI");
    	    result.getSubjects().add(new SubjectDTO(urlEnc, subj_str));
    	  }
    	}

        n2 = xpath.selectNodeList(pndsdc_description,"./dcterms:spatial",pndsdc_description);
        for ( int j=0; j<n2.getLength(); j++ ) {
          Element sub_node = (Element)n2.item(j);
          // String spat_str = getDataFromFile(sub_node,"./text()");
    	  String spat_str = sub_node.getTextContent();
          if ((spat_str != null) && (spat_str.length() > 0)) {
            String urlEnc = sub_node.getAttribute("encSchemeURI");
            result.getSpatial_terms().add(new SpatialCoverageDTO(urlEnc, spat_str));
          }
        }

        n2 = xpath.selectNodeList(pndsdc_description,"./dc:creator",pndsdc_description);
        for ( int j=0; j<n2.getLength(); j++ ) {
          Element sub_node = (Element)n2.item(j);
          // String creat_str = getDataFromFile(sub_node,"./text()");
          String creat_str = sub_node.getTextContent();
          if ((creat_str != null) && (creat_str.length() > 0)) {
            result.getCreators().add(new CreatorDTO(creat_str));
          }
        }
/*
        n2 = xpath.selectNodeList(pndsdc_description,"./dc:availablitiy",pndsdc_description);
        for ( int j=0; j<n2.getLength(); j++ ) {
          Element sub_node = (Element)n2.item(j);
          String = getDataFromFile(sub_node,"./text()");
          if (( != null) && (.length() > 0)) {
            String urlEnc = sub_node.getAttribute("encSchemeURI");
            result.getSubjects().add(new SubjectDTO(urlEnc, subj));
          }
       }
*/

        log.info("Elapsed before upload "+(System.currentTimeMillis()-start_time));
        // Upload the new resource to the server
        controller.upload(result,
                          id,
                          "CollectBritain",  // Record Source
                          "CollectBritain",                      // Publisher
                          "CollectBritain-Credentials",          // Publisher Credentials
                          getPublishURL(),
                          getTargetCollection(),
                          default_authority);

        insert_count++;

        long elapsed = System.currentTimeMillis() - start_time;
        rac.registerValue(elapsed);
        log.info("This record: "+elapsed+", Average : "+rac.getAverage());
      }
      setStatus(UploadStatus.COMPLETED_OK);
    }
    catch ( javax.xml.parsers.ParserConfigurationException pce ) {
      error_count++;
      pce.printStackTrace();
    }
    catch ( java.io.UnsupportedEncodingException uee ) {
      error_count++;
      uee.printStackTrace();
    }
    catch ( org.xml.sax.SAXException saxe ) {
      error_count++;
      saxe.printStackTrace();
    }
    catch ( java.io.IOException ioe ) {
      error_count++;
      ioe.printStackTrace();
    }
    catch ( javax.xml.transform.TransformerException tfe ) {
      error_count++;
      tfe.printStackTrace();
    }
    catch ( com.k_int.ia.data_upload.DataPublishException dpe ) {
      error_count++;
      dpe.printStackTrace();
    }
    catch ( Exception ex ) {
        error_count++;
        ex.printStackTrace();
      }

    if(this.getStatus()==UploadStatus.BUSY)
        this.setStatus(UploadStatus.FAILED);

    //setStatus(com.k_int.it4me.Messages.getString("HelpYourselfPublisher.26")); //$NON-NLS-1$

    running = false;
    controller.notifyComplete(this);
    log.debug("Completed run");
    System.err.println("Finished Processing");
  }
 
 
  public com.k_int.ia.codbif.xdevicegui.defs.XDLayoutHDO getLayout() {
    return new com.k_int.ia.codbif.xdevicegui.defs.XDLayoutHDO(
        "IT For Me Publisher",
        "com.k_int.it4me.messages",
        new com.k_int.ia.codbif.xdevicegui.defs.XDNameValuePairPanel(config_fields));
  }
  public String getTargetCollection() {
    return targetCollection;
  }
  public void setTargetCollection(String targetCollection) {
    this.targetCollection = targetCollection;
  }
 
  public String getDataFromFile(Node n,String path) throws javax.xml.transform.TransformerException {
    String retval = null;
    Node temp_node = xpath.selectSingleNode(n, path ,n);
    if ( temp_node != null ) {
      String data_string = temp_node.getNodeValue();
      retval = data_string;
    }
    return retval;
  }

  public String getChildNodeText(Element parent, String child_ns, String child_name) {
    String retval = null;
    NodeList nl = parent.getElementsByTagNameNS(child_ns, child_name);
    if ( nl.getLength() > 0 ) {
      retval = nl.item(0).getTextContent();
    }
    return retval;
  }
  
  public String getSourceURL() {
      return sourceURL;
  }
  
  public void setSourceURL(String sourceURL) {
      this.sourceURL=sourceURL;
  }
  
}
