package com.k_int.discover.lookup.collection;

import com.k_int.aggregator.datamodel.AggregatorCollectionHDO;
import com.k_int.discover.datamodel.CultureGrid_AutomaticCollLinkHDO;
import com.k_int.discover.datamodel.CultureGrid_BaseHDO;
import com.k_int.discover.datamodel.CultureGrid_CollectionHDO;
import com.opensymphony.xwork2.ActionSupport;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * An action that given a specific id or collection code looks up the specified
 * collection and returns all of the relevant information about it as well as
 * pointers to the parent and children collections
 * 
 * @author rpb rich@k-int.com
 * @version 1.0 19.01.12
 * 
 */
public class LookupCollection extends ActionSupport implements ServletRequestAware, ApplicationContextAware {
	private static final long serialVersionUID = -1884369503898727298L;

	private static Log log = LogFactory.getLog(LookupCollection.class);
    
    protected HttpServletRequest request;
    protected ApplicationContext ctx;
    protected SessionFactory factory;

    public void setServletRequest(HttpServletRequest request) { this.request = request; }
    public void setApplicationContext(ApplicationContext ctx) {	this.ctx = ctx; }
    public void setSessionFactory(SessionFactory factory) { this.factory = factory; }

    private String collInfo = "";

    public String getCollInfo() {
        return this.collInfo;
    }
    
    @Override
    public String execute() {
        log.debug("LookupCollection::execute method called");
        
        String returnValue = SUCCESS;

        Session sess = null;

        try {
            sess = factory.openSession();

            String identifierStr = request.getParameter("id");
            Long identifier = 0l;
            String collCode = request.getParameter("code");
            String respType = request.getParameter("format");
            if ( respType == null || "".equals(respType.trim()) )
                 respType = "JSON";
            
            log.debug("identifierStr = " + identifierStr + " and collCode = " + collCode + " and respType = " + respType);

            String lookupType = null;

            if ( identifierStr != null && !"".equals(identifierStr.trim()) ) {
                identifier = new Long(identifierStr);
                lookupType = "identifier";
            } else if ( collCode != null && !"".equals(collCode.trim()) ) {
                lookupType = "collCode";
            }
            
            
            if ( lookupType == null ) {
                // Nothing to lookup - return an error
                
                // TODO
            } else {

                // Go and get the specified collection
                AggregatorCollectionHDO coll = null;
                
                if ( "identifier".equals(lookupType) ) {
                    coll = AggregatorCollectionHDO.lookupById(sess, identifier);
                } else {
                    coll = AggregatorCollectionHDO.lookup(sess, collCode);
                }
                
                if ( coll == null ) {
                    // No collection found - return an error..
                    
                    // TODO
                } else {
                    // We have a collection - go and find the parent collection if there is one
                    AggregatorCollectionHDO parentColl = AggregatorCollectionHDO.lookupByChildCollectionCode(sess, coll.getCollectionCode());
                    String parentCollCode = "";
                    Long parentId = -1l;
                    String parentName = "";
                    if ( parentColl != null ) {
                        parentCollCode = parentColl.getCollectionCode();
                        parentId = parentColl.getId();
                        parentName = parentColl.getName();
                    }
                    
                    boolean isDeleted = false;
                    if ( coll.getManagementInfo().getDeletedDate() != null ) 
                        isDeleted = true;
                    
                    // Set up the information about children codes and ids
                    StringBuilder childBuilder = new StringBuilder();
                    
                    // Loop through each of the children and add their information if they're not deleted
                    for(AggregatorCollectionHDO aChild: coll.getChildrenCollections() ) {
                        
                        if ( aChild.getManagementInfo().getDeletedDate() == null ) {
                            // This collection hasn't been deleted - add to the list
                            
                            if ( childBuilder.length() != 0 ) {
                                childBuilder.append(",");
                            }
                            
                            childBuilder.append("{\"id\":").append(aChild.getId()).append(",");
                            childBuilder.append("\"collCode\":\"").append(aChild.getCollectionCode()).append("\",");
                            childBuilder.append("\"name\":\"").append(aChild.getName()).append("\"}");
                        }
                        
                    }
                    
                    String childData = childBuilder.toString();
                    
                    // Get relevant information from the linked CLD if there is one..
                    StringBuilder linkedCLDBuilder = new StringBuilder();
                    linkedCLDBuilder.append("{");
                    if ( coll.getLinkedResource() != null )  {
                        
                        // Get the datamodel object that is linked to..
                        CultureGrid_BaseHDO linkedResBase = CultureGrid_BaseHDO.lookupByResourceId(sess, coll.getLinkedResource().getId());
                        
                        if ( linkedResBase != null  && linkedResBase instanceof CultureGrid_CollectionHDO ) {

                            CultureGrid_CollectionHDO linkedResColl = (CultureGrid_CollectionHDO)linkedResBase;

                            linkedCLDBuilder.append("\"resourceId\":\"").append(coll.getLinkedResource().getId()).append("\",");
                            linkedCLDBuilder.append("\"title\":\"").append(linkedResColl.getTitle()).append("\",");
                            linkedCLDBuilder.append("\"associatedColls\":[");
                                if ( linkedResColl.getAutoData() != null && linkedResColl.getAutoData().getAssociatedColls() != null && !linkedResColl.getAutoData().getAssociatedColls().isEmpty()) {
                                    // We have something to add in..
                                    boolean assocOutput = false;
                                    for(CultureGrid_AutomaticCollLinkHDO anAssoc: linkedResColl.getAutoData().getAssociatedColls()) {
                                        if ( assocOutput )
                                            linkedCLDBuilder.append(",");
                                        
                                        linkedCLDBuilder.append("{");
                                        linkedCLDBuilder.append("\"id\":\"").append(anAssoc.getCollId()).append("\",");
                                        linkedCLDBuilder.append("\"title\":\"").append(anAssoc.getCollTitle()).append("\",");
                                        linkedCLDBuilder.append("\"code\":\"").append(anAssoc.getCollCode()).append("\"");
                                        linkedCLDBuilder.append("}");
                                        assocOutput = true;
                                    }
                                }
                            linkedCLDBuilder.append("]");

                        } else {
                            log.error("No linked resource collection found even though a resource was apparently linked!");
                        }
                    }
                    linkedCLDBuilder.append("}");

                    String linkedCldData = linkedCLDBuilder.toString();
                    
                    // Now we have everything we need - set up the return information
                    
                    StringBuilder retvalBuilder = new StringBuilder();
                    retvalBuilder.append("{\"id\":").append(coll.getId()).append(",");
                    retvalBuilder.append("\"collCode\":\"").append(coll.getCollectionCode()).append("\",");
                    retvalBuilder.append("\"name\":\"").append(coll.getName()).append("\",");
                    retvalBuilder.append("\"description\":\"");
                    if ( coll.getDescription() != null ) 
                        retvalBuilder.append(coll.getDescription());
                    retvalBuilder.append("\",");
                    retvalBuilder.append("\"public\":").append(coll.getManagementInfo().getSearchable()).append(",");
                    retvalBuilder.append("\"showChildren\":").append(coll.getManagementInfo().getSearchShowChildCollections()).append(",");
                    retvalBuilder.append("\"type\":\"").append(coll.getCollectionType().getIdentifier()).append("\",");
                    retvalBuilder.append("\"parentCode\":\"").append(parentCollCode).append("\",");
                    retvalBuilder.append("\"parentId\":").append(parentId).append(",");
                    retvalBuilder.append("\"parentName\":\"").append(parentName).append("\",");
                    retvalBuilder.append("\"children\":[").append(childData).append("],");
                    retvalBuilder.append("\"deleted\":").append(isDeleted).append(",");
                    retvalBuilder.append("\"linked_cld\":").append(linkedCldData);
                    
                    retvalBuilder.append("}");

                    // Just remember the information we've built up so it can be returned
                    collInfo = retvalBuilder.toString();
                }

                
            }
            
            request.setAttribute("collInfo", this.collInfo);

            
        } catch (HibernateException he) {
            log.error("HibernateException thrown: " + he.getMessage());
            he.printStackTrace();
        } finally {
            if ( sess != null ) {
                try {
                    sess.close();
                } catch (HibernateException he) {
                    // Can't do anything!
                }
            }
        }
        
        return returnValue;
    }


}
