/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 * http://www.dspace.org/license/
 */
package org.dspace.xoai.data;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.dspace.core.Context;
import org.dspace.storage.rdbms.DatabaseManager;
import org.dspace.storage.rdbms.TableRow;
import org.dspace.storage.rdbms.TableRowIterator;

import com.lyncode.xoai.dataprovider.core.ListSetsResult;
import com.lyncode.xoai.dataprovider.core.Set;
import com.lyncode.xoai.dataprovider.data.AbstractSetRepository;
import org.dspace.content.Collection;
import org.dspace.content.Community;
import org.dspace.content.DSpaceObject;
import org.dspace.core.Constants;
import org.dspace.handle.HandleManager;
//import javax.servlet.jsp.jstl.fmt.LocaleSupport;

/**
 * 
 * @author Lyncode Development Team <dspace@lyncode.com>
 */
public class DSpaceSetRepository extends AbstractSetRepository
{
    private static Logger log = LogManager.getLogger(DSpaceSetRepository.class);

    private Context _context;

    public DSpaceSetRepository(Context context)
    {
        _context = context;
    }

    private int getCommunityCount()
    {
        String query = "SELECT COUNT(*) as count FROM community where name like '%@%'";
        try
        {
            TableRowIterator iterator = DatabaseManager.query(_context, query);
            if (iterator.hasNext())
                return (int) iterator.next().getLongColumn("count");
        }
        catch (SQLException e)
        {
            log.error(e.getMessage(), e);
        }
        return 0;
    }

    private int getCollectionCount()
    {
        String query = "SELECT COUNT(*) as count FROM collection where name like '%@%'";
        try
        {
            TableRowIterator iterator = DatabaseManager.query(_context, query);
            if (iterator.hasNext())
                return (int) iterator.next().getLongColumn("count");
        }
        catch (SQLException e)
        {
            log.error(e.getMessage(), e);
        }
        return 0;
    }

    private List<Set> community(int offset, int length)
    {
        List<Set> array = new ArrayList<Set>();
        //Cambio para GV: mostrar en ListSets solo los que tienen @ en el nombre (quitar ondarenet)
        StringBuffer query = new StringBuffer("SELECT community_id, name, handle FROM community c, handle h WHERE h.resource_id=community_id AND h.resource_type_id=? AND NAME LIKE '%@%' ORDER BY community_id");
        List<Serializable> params = new ArrayList<Serializable>();
        params.add(Constants.COMMUNITY);

        DatabaseManager.applyOffsetAndLimit(query,params,offset,length);

        try
        {
            TableRowIterator iterator = DatabaseManager.query(_context, query.toString(),
                    params.toArray());
            int i = 0;
            while (iterator.hasNext() && i < length)
            {
                TableRow row = iterator.next();
                
                //Cambio para GV: Traducir los nombres del comando ListSets
                String nombre = row.getStringColumn("name");
                
                //Cambio para GV: mostrar en ListSets solo los que tienen @ en el nombre (quitar ondarenet)
                boolean nombre_traducir = false;
                
				  	    if ((nombre != null) && (!nombre.equals(""))) {
				    	    char[] nombre_sep = nombre.toCharArray();
				    	    if (nombre_sep[4] == '@') {
					      	   nombre = poner_nombre(nombre.substring(4));
					      	   nombre_traducir = true;
					      	}
				      	}
                
                if (nombre_traducir) array.add(DSpaceSet.newDSpaceCommunitySet(row.getStringColumn("handle"), nombre));
                i++;
            }
        }
        catch (SQLException e)
        {
            log.error(e.getMessage(), e);
        }
        return array;
    }

		private String poner_nombre(String coleccion) {
				String result = coleccion;
				if (result.equals("@HEMEROTECA"))                            result = "HEMEROTECA";
				if (result.equals("@HEMEROTECA_HISTORICA"))                  result = "Prensa Histórica";
				if (result.equals("@HEMEROTECA_REVISTAS"))                   result = "Revistas";
				if (result.equals("@ONDARENET"))                             result = "ONDARENET";
				if (result.equals("@DIPUTACION"))                            result = "DIPUTACIÓN FORAL DE ÁLAVA";
				if (result.equals("@DIPUTACION_IRADIER"))                    result = "Fondo Manuel Iradier";
				if (result.equals("@DIPUTACION_COMUNIDAD_MICAELA"))          result = "Fondo Micaela Portilla";
				if (result.equals("@DIPUTACION_PORTILLA_ARTICULOS"))         result = "Artículos";
				if (result.equals("@DIPUTACION_PORTILLA_LIBROS"))            result = "Libros";
				if (result.equals("@DIPUTACION_PORTILLA_TESIS"))             result = "Tesis";
				if (result.equals("@DIPUTACION_PORTILLA_FICHAS_HERALDICA"))  result = "Fichas heráldicas";
				if (result.equals("@DIPUTACION_PORTILLA_FICHAS_TRABAJO"))    result = "Fichas de trabajo de campo";
				if (result.equals("@DIPUTACION_PORTILLA_FICHAS_INVENTARIO")) result = "Fichas de inventario artístico";
				if (result.equals("@DIPUTACION_PRENSA_HISTORICA"))           result = "Prensa Histórica";
				if (result.equals("@PARLAMENTO"))                            result = "PARLAMENTO VASCO";
				if (result.equals("@PARLAMENTO_MANUSCRITOS"))                result = "Manuscritos";
				if (result.equals("@PARLAMENTO_MONOGRAFIAS"))                result = "Monografías";
				if (result.equals("@LOIOLA"))                                result = "SANTUARIO DE LOIOLA";
				if (result.equals("@LOIOLA_MONOGRAFIAS"))                    result = "Monografías";
				if (result.equals("@JUANSANMARTIN_COMU"))                    result = "BIBLIOTECA JUAN SAN MARTIN DE EIBAR";
				if (result.equals("@JUANSANMARTIN_MONOGRAFIAS"))             result = "Monografías";
				if (result.equals("@BFB"))                                   result = "BIBLIOTECA FORAL DE BIZKAIA";
				if (result.equals("@BFB_PRENSA_HISTORICA"))                  result = "Prensa Histórica";
				if (result.equals("@BFB_INCUNABLES"))                        result = "Incunables";
				if (result.equals("@DIPUTACION_MONOGRAFIAS"))                result = "Monografías";
				if (result.equals("@DIPUTACION_REVISTAS"))                   result = "Revistas";
				if (result.equals("@ARCHIVO_MUNICIPAL_PILAR"))               result = "ARCHIVO MUNICIPAL DE VITORIA-GASTEIZ PILAR ARÓSTEGUI";
				if (result.equals("@ARCHIVO_MUNICIPAL_PILAR_PRENSA"))        result = "Prensa Histórica";
				if (result.equals("@ARCHIVO_MUNICIPAL_CARTELES"))            result = "Carteles";
				if (result.equals("@ARCHIVO_MUNICIPAL_CARTELES_CARNAVAL"))   result = "Carnavales";
				if (result.equals("@ARCHIVO_MUNICIPAL_CARTELES_FIESTAS"))    result = "Fiestas de Vitoria";
				if (result.equals("@ERESBIL"))                               result = "ERESBIL: ARCHIVO VASCO DE LA MÚSICA";
				if (result.equals("@ERESBIL_PARTITURAS"))                    result = "Partituras";
				if (result.equals("@ERESBIL_ARCHIVOS_SONOROS"))              result = "Archivos sonoros";
				if (result.equals("@Sounds"))                                result = "Partituras";
				if (result.equals("@FSS"))                                   result = "FUNDACION SANCHO EL SABIO";
				if (result.equals("@FSS_PRENSA_HISTORICA"))                  result = "Prensa Histórica";
				if (result.equals("@FSS_MANUSCRITOS"))                       result = "Manuscritos";
				if (result.equals("@FSS_MONOGRAFIAS"))                       result = "Monografías";
				if (result.equals("@BM_MANUEL_LEKUONA"))                     result = "BIBLIOTECA MUNICIPAL MANUEL LEKUONA DE OIARTZUN";
				if (result.equals("@BM_MANUEL_LEKUONA_MONOGRAFIAS"))         result = "Monografías";
				if (result.equals("@BM_MANUEL_LEKUONA_REVISTAS"))            result = "Revistas";
				if (result.equals("@BM_IKUST_ALAIA"))                        result = "BIBLIOTECA MUNICIPAL IKUST-ALAIA DE IRUN";
				if (result.equals("@BM_IKUST_ALAIA_MONOGRAFIAS"))            result = "Monografías";
				if (result.equals("@BM_IKUST_ALAIA_FOTOGRAFIAS"))            result = "Fotografías";
				if (result.equals("@BM_IKUST_ALAIA_PRENSA"))                 result = "Prensa Histórica";
				if (result.equals("@DEPOSITO_LEGAL"))                        result = "DEPÓSITO LEGAL";
				if (result.equals("@DEPOSITO_LEGAL_REVISTAS"))               result = "Revistas";
				if (result.equals("@DEPOSITO_LEGAL_MONOGRAFIAS"))            result = "Monografías";
				if (result.equals("@DEPOSITO_LEGAL_PRENSA_HISTORICA"))       result = "Prensa Histórica";
				if (result.equals("@BIB_SEMINARIO_DIOCESANO"))               result = "BIBLIOTECA DEL SEMINARIO DIOCESANO DE VITORIA-GASTEIZ";
				if (result.equals("@BIB_SEMINARIO_DIOCESANO_MONOGRAFIAS"))   result = "Monografías";
				if (result.equals("@BIB_SEMINARIO_DIOCESANO_REVISTAS"))      result = "Revistas";
				if (result.equals("@RSBAP"))                                 result = "REAL SOCIEDAD BASCONGADA DE LOS AMIGOS DEL PAÍS";
				if (result.equals("@RSBAP_BOLETINES"))                       result = "Boletines y Extractos";
				if (result.equals("@RSBAP_MONOGRAFIAS"))                     result = "Monografías";
				if (result.equals("@RSBAP_PRENSA_HISTORICA"))                result = "Prensa Histórica";
				if (result.equals("@BMLLODIO"))                              result = "BIBLIOTECA MUNICIPAL DE LAUDIO/LLODIO";
				if (result.equals("@BMLLODIO_REVISTAS"))                     result = "Revistas";
				if (result.equals("@BMLLODIO_MONOGRAFIAS"))                  result = "Monografías";
				if (result.equals("@URAZANDI_COMU"))                         result = "URAZANDI";
				if (result.equals("@URAZANDI_BOLETINES"))                    result = "Boletines";
				if (result.equals("@URAZANDI_MEMORIAS"))                     result = "Memorias";
				if (result.equals("@URAZANDI_MONOGRAFIAS"))                  result = "Monografías";
				if (result.equals("@URAZANDI_PRENSA_HISTORICA"))             result = "Prensa Histórica";
				if (result.equals("@URAZANDI_REVISTAS"))                     result = "Revistas";
				if (result.equals("@BMC_DONOSTIA_COMUNIDAD"))                result = "BIBLIOTECA MUNICIPAL CENTRAL DE SAN SEBASTIÁN";
				if (result.equals("@BMC_DONOSTIA_PRENSA_HISTORICA"))         result = "Prensa Histórica";
				if (result.equals("@SANT_ARANTZAZU"))                        result = "SANTUARIO DE ARANZAZU";
				if (result.equals("@SANT_ARANTZAZU_REVISTAS"))               result = "Revistas";
				if (result.equals("@BMGETXO"))                               result = "BIBLIOTECA MUNICIPAL DE GETXO";
				if (result.equals("@BMGETXO_PRENSA"))                        result = "Prensa Histórica";
				if (result.equals("@BMGETXO_REVISTAS"))                      result = "Revistas";
				if (result.equals("@BMGETXO_MONOGRAFIAS"))                   result = "Monografías";
				return result;
		}

    private List<Set> collection(int offset, int length)
    {
        List<Set> array = new ArrayList<Set>();
        
        //Cambio para GV: mostrar los que tienen @ en el nombre (quitar ondarenet)
        StringBuffer query = new StringBuffer("SELECT collection_id, name, handle FROM collection c, handle h WHERE h.resource_id=collection_id AND h.resource_type_id=? AND NAME LIKE '%@%' ORDER BY collection_id");
        List params = new ArrayList();
        params.add(Constants.COLLECTION);

        DatabaseManager.applyOffsetAndLimit(query,params,offset,length);

        try
        {
            TableRowIterator iterator = DatabaseManager.query(_context, query.toString(),
                    params.toArray());
            int i = 0;
            while (iterator.hasNext() && i < length)
            {
                TableRow row = iterator.next();
                
                //Cambio para GV: Traducir los nombres del comando ListSets
                String nombre = row.getStringColumn("name");
                //Cambio para GV: mostrar en ListSets solo los que tienen @ en el nombre (quitar ondarenet)
                boolean nombre_traducir = false;
                
				  	    if ((nombre != null) && (!nombre.equals(""))) {
				    	    char[] nombre_sep = nombre.toCharArray();
				    	    if (nombre_sep.length>4) {
						    	    if (nombre_sep[4] == '@') {
							      	   nombre = poner_nombre(nombre.substring(4));
							      	   nombre_traducir = true;
							      	}
						      }
				      	}
                
                if (nombre_traducir) array.add(DSpaceSet.newDSpaceCollectionSet(row.getStringColumn("handle"), nombre));
                i++;
            }
        }
        catch (SQLException e)
        {
            log.error(e.getMessage(), e);
        }
        return array;
    }
    
    //Cambio para GV: Sets virtuales
    private List<Set> setsVirtuales()
    {
	    List<Set> array = new ArrayList<Set>();
			array.add(new Set("europeana", "Europeana"));
			/*
			array.add(DSpaceSet.newDSpaceCollectionSet("monographs","Monographs"));
			array.add(DSpaceSet.newDSpaceCollectionSet("manuscripts","Manuscripts"));
			array.add(DSpaceSet.newDSpaceCollectionSet("incunables","Incunables"));
			array.add(DSpaceSet.newDSpaceCollectionSet("newspapers","Newspapers"));
			array.add(DSpaceSet.newDSpaceCollectionSet("magazines","Magazines"));
			array.add(DSpaceSet.newDSpaceCollectionSet("sheet_music","Sheet_music"));
			*/
			return array;
		}

    @Override
    public ListSetsResult retrieveSets(int offset, int length)
    {    	
        // Only database sets (virtual sets are added by lyncode common library)
        log.debug("Quering sets. Offset: " + offset + " - Length: " + length);
        List<Set> array = new ArrayList<Set>();
        int communityCount = this.getCommunityCount();
        log.debug("Communities: " + communityCount);
        int collectionCount = this.getCollectionCount();
        log.debug("Collections: " + collectionCount);

        if (offset < communityCount)
        {
            if (offset + length > communityCount)
            {
                // Add some collections
                List<Set> tmp = community(offset, length);
                array.addAll(tmp);
                array.addAll(collection(0, length - tmp.size()));
            }
            else array.addAll(community(offset, length));
        }
        else if (offset < communityCount + collectionCount)
        {
            array.addAll(collection(offset - communityCount, length));
        }
        log.debug("Has More Results: "
                + ((offset + length < communityCount + collectionCount) ? "Yes"
                        : "No"));
                        
        array.addAll(setsVirtuales());
        return new ListSetsResult(offset + length < communityCount + collectionCount, array, communityCount + collectionCount);
        
    }

    @Override
    public boolean supportSets()
    {
        return true;
    }

    @Override
    public boolean exists(String setSpec)
    {
        if (setSpec.startsWith("col_"))
        {
            try
            {
                DSpaceObject dso = HandleManager.resolveToObject(_context,
                        setSpec.replace("col_", "").replace("_", "/"));
                if (dso == null || !(dso instanceof Collection))
                    return false;
                return true;
            }
            catch (Exception ex)
            {
                log.error(ex.getMessage(), ex);
            }
        }
        else if (setSpec.startsWith("com_"))
        {
            try
            {
                DSpaceObject dso = HandleManager.resolveToObject(_context,
                        setSpec.replace("com_", "").replace("_", "/"));
                if (dso == null || !(dso instanceof Community))
                    return false;
                return true;
            }
            catch (Exception ex)
            {
                log.error(ex.getMessage(), ex);
            }
        }
        return false;
    }

}
