/*
 * Copyright (C) 2003-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the
 * License at http://www.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.search.lucene;

import com.arsdigita.domain.DomainObject;
import com.arsdigita.persistence.OID;
import com.arsdigita.kernel.Party;
import com.arsdigita.search.Search;
import com.arsdigita.search.ContentProvider;
import com.arsdigita.search.ContentType;
import com.arsdigita.search.MetadataProvider;
import com.arsdigita.search.MetadataProviderRegistry;
import com.arsdigita.util.Assert;

import java.math.BigDecimal;

import org.apache.log4j.Logger;


public class DocumentObserver implements com.arsdigita.search.DocumentObserver {

    private static final Logger s_log = 
        Logger.getLogger(DocumentObserver.class);
    
    /**
     * Invoked after a searchable object has been 
     * created or updated.
     *
     * @param dobj the updated object
     */
    public void onSave(DomainObject dobj) {
        MetadataProvider adapter = MetadataProviderRegistry
            .findAdapter(dobj.getObjectType());

        BigDecimal id = (BigDecimal)dobj.getOID().get("id");
        Assert.exists(id, BigDecimal.class);
        Document doc = Document.retrieve(id);
        if (doc == null) {
            if (s_log.isDebugEnabled()) {
                s_log.debug("Creating new document");
            }
            doc = Document.create(id);
            doc.setType(dobj.getObjectType().getQualifiedName());
        }
        if (adapter != null) {
            if (s_log.isDebugEnabled()) {
                s_log.debug("Processing object " + dobj.getOID() + 
                            " using new adapters");
            } 

            doc.setTypeSpecificInfo(adapter.getTypeSpecificInfo(dobj));
            doc.setLocale(adapter.getLocale(dobj));
            doc.setTitle(adapter.getTitle(dobj));
            doc.setSummary(adapter.getSummary(dobj));
            doc.setCreationDate(adapter.getCreationDate(dobj));
            Party party = adapter.getCreationParty(dobj);
            doc.setCreationParty(party == null ? null : party.getID());
            doc.setLastModifiedDate(adapter.getLastModifiedDate(dobj));
            party = adapter.getLastModifiedParty(dobj);
            doc.setLastModifiedParty(party == null ? null : party.getID());
            
            ContentProvider[] content = adapter.getContent(dobj,
                                                           ContentType.TEXT);
            StringBuffer buf = new StringBuffer("");
            for (int i = 0 ; i < content.length ; i++) {
                Assert.truth(content[i].getType().equals(ContentType.TEXT),
                             "content is text");
                buf.append(new String(content[i].getBytes()));
            }
            doc.setContent(buf.toString());
        } else {
            if (s_log.isDebugEnabled()) {
                s_log.debug("Processing object " + dobj.getOID() + 
                            " using old adapters");
            } 

            Registry reg = Registry.getInstance();
            Adapter ladapter = reg.getAdapter(dobj.getObjectType());
            Assert.exists(ladapter, Adapter.class);

            doc.setTypeSpecificInfo(ladapter.getTypeSpecificInfo(dobj));
            doc.setLocale(ladapter.getLocale(dobj));
            doc.setTitle(ladapter.getTitle(dobj));
            doc.setSummary(ladapter.getSummary(dobj));
            doc.setCreationDate(ladapter.getCreationDate(dobj));
            Party party = ladapter.getCreationParty(dobj);
            doc.setCreationParty(party == null ? null : party.getID());
            doc.setLastModifiedDate(ladapter.getLastModifiedDate(dobj));
            party = ladapter.getLastModifiedParty(dobj);
            doc.setLastModifiedParty(party == null ? null : party.getID());
            doc.setContent(ladapter.getContent(dobj));
        }
        
        doc.setDirty(true);
        doc.save();
    }

    /**
     * Invoked after a searchable object has been 
     * deleted. NB, the only guarenteed valid method
     * that can be invoked on the DomainObject is
     * getOID().
     *
     * @param dobj the deleted object
     */
    public void onDelete(DomainObject dobj) {
        BigDecimal id = (BigDecimal)dobj.getOID().get("id");
        Assert.exists(id, BigDecimal.class);
        Document doc = Document.retrieve(id);
        if (doc != null) {
            doc.setDeleted(true);
            doc.setDirty(true);
            doc.save();
        }
    }
}
