/*
 * Copyright 2001-2008 The Apache Software Foundation.
 * 
 * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
package org.apache.juddi.api.impl;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.UUID;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jws.WebService;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import javax.xml.datatype.DatatypeConfigurationException;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.ws.BindingProvider;
import javax.xml.ws.Holder;

import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.juddi.api.util.CustodyTransferQuery;
import org.apache.juddi.api.util.QueryStatus;
import org.apache.juddi.config.AppConfig;
import org.apache.juddi.config.PersistenceManager;
import org.apache.juddi.config.Property;
import org.apache.juddi.mapping.MappingApiToModel;
import org.apache.juddi.mapping.MappingModelToApi;
import org.apache.juddi.model.BindingTemplate;
import org.apache.juddi.model.BusinessEntity;
import org.apache.juddi.model.BusinessService;
import org.apache.juddi.model.Operator;
import org.apache.juddi.model.Tmodel;
import org.apache.juddi.model.TransferTokenKey;
import org.apache.juddi.model.UddiEntity;
import org.apache.juddi.model.UddiEntityPublisher;
import org.apache.juddi.query.util.DynamicQuery;
import org.apache.juddi.replication.ReplicationNotifier;
import org.apache.juddi.v3.client.UDDIService;
import org.apache.juddi.v3.error.ErrorMessage;
import org.apache.juddi.v3.error.FatalErrorException;
import org.apache.juddi.v3.error.InvalidValueException;
import org.apache.juddi.v3.error.TransferNotAllowedException;
import org.apache.juddi.validation.ValidateCustodyTransfer;
import org.uddi.api_v3.OperationalInfo;
import org.uddi.custody_v3.DiscardTransferToken;
import org.uddi.custody_v3.KeyBag;
import org.uddi.custody_v3.TransferEntities;
import org.uddi.custody_v3.TransferOperationalInfo;
import org.uddi.repl_v3.ChangeRecord;
import org.uddi.repl_v3.ChangeRecordIDType;
import org.uddi.repl_v3.ChangeRecordNewData;
import org.uddi.repl_v3.TransferCustody;
import org.uddi.v3_service.DispositionReportFaultMessage;
import org.uddi.v3_service.UDDICustodyTransferPortType;
import org.uddi.v3_service.UDDIReplicationPortType;

/**
 * This implements the UDDI v3 Custody Transfer API web service
 *
 */
@WebService(serviceName = "UDDICustodyTransferService",
        endpointInterface = "org.uddi.v3_service.UDDICustodyTransferPortType",
        targetNamespace = "urn:uddi-org:v3_service")
public class UDDICustodyTransferImpl extends AuthenticatedService implements UDDICustodyTransferPortType {

        public static final String TRANSFER_TOKEN_PREFIX = "transfertoken:";
        public static final int DEFAULT_TRANSFEREXPIRATION_DAYS = 3;

        private static Log logger = LogFactory.getLog(UDDICustodyTransferImpl.class);

        private static DatatypeFactory df = null;
        private UDDIServiceCounter serviceCounter;

        public UDDICustodyTransferImpl() {
                super();
                serviceCounter = ServiceCounterLifecycleResource.getServiceCounter(this.getClass());
                init();
        }
        
        private static synchronized void init() {
                if (df == null) {
                        try {
                                df = DatatypeFactory.newInstance();
                        } catch (DatatypeConfigurationException ex) {
                                Logger.getLogger(UDDICustodyTransferImpl.class.getName()).log(Level.SEVERE, null, ex);
                        }
                }
        }

        @SuppressWarnings("unchecked")
        @Override
        public void discardTransferToken(DiscardTransferToken body)
                throws DispositionReportFaultMessage {
                long startTime = System.currentTimeMillis();

                EntityManager em = PersistenceManager.getEntityManager();
                EntityTransaction tx = em.getTransaction();
                try {
                        tx.begin();

                        UddiEntityPublisher publisher = this.getEntityPublisher(em, body.getAuthInfo());

                        new ValidateCustodyTransfer(publisher).validateDiscardTransferToken(em, body);

                        org.uddi.custody_v3.TransferToken apiTransferToken = body.getTransferToken();
                        if (apiTransferToken != null) {
                                String transferTokenId;
                                try {
                                    transferTokenId = new String(apiTransferToken.getOpaqueToken(), UTF8);
                                } catch (UnsupportedEncodingException ex) {
                                    throw new InvalidValueException(new ErrorMessage("errors.stringEncoding"));
                                }
                                org.apache.juddi.model.TransferToken modelTransferToken = em.find(org.apache.juddi.model.TransferToken.class, transferTokenId);
                                if (modelTransferToken != null) {
                                        em.remove(modelTransferToken);
                                }
                        }

                        KeyBag keyBag = body.getKeyBag();
                        if (keyBag != null) {
                                List<String> keyList = keyBag.getKey();
                                Vector<DynamicQuery.Parameter> params = new Vector<DynamicQuery.Parameter>(0);
                                for (String key : keyList) {
                                        // Creating parameters for key-checking query
                                        DynamicQuery.Parameter param = new DynamicQuery.Parameter("UPPER(ttk.entityKey)",
                                                key.toUpperCase(),
                                                DynamicQuery.PREDICATE_EQUALS);

                                        params.add(param);
                                }

                                // Find the associated transfer tokens and remove them.
                                DynamicQuery getTokensQry = new DynamicQuery();
                                getTokensQry.append("select distinct ttk.transferToken from TransferTokenKey ttk").pad();
                                getTokensQry.WHERE().pad().appendGroupedOr(params.toArray(new DynamicQuery.Parameter[0]));

                                Query qry = getTokensQry.buildJPAQuery(em);
                                List<org.apache.juddi.model.TransferToken> tokensToDelete = qry.getResultList();
                                if (tokensToDelete != null && tokensToDelete.size() > 0) {
                                        for (org.apache.juddi.model.TransferToken tt : tokensToDelete) {
                                                em.remove(tt);
                                        }
                                }
                        }

                        tx.commit();
                        long procTime = System.currentTimeMillis() - startTime;
                        serviceCounter.update(CustodyTransferQuery.DISCARD_TRANSFERTOKEN,
                                QueryStatus.SUCCESS, procTime);

                } finally {
                        if (tx.isActive()) {
                                tx.rollback();
                        }
                        em.close();
                }
        }

        @Override
        public void getTransferToken(String authInfo, KeyBag keyBag,
                Holder<String> nodeID, Holder<XMLGregorianCalendar> expirationTime,
                Holder<byte[]> opaqueToken) throws DispositionReportFaultMessage {
                long startTime = System.currentTimeMillis();

                EntityManager em = PersistenceManager.getEntityManager();
                EntityTransaction tx = em.getTransaction();
                try {
                        tx.begin();

                        UddiEntityPublisher publisher = this.getEntityPublisher(em, authInfo);

                        new ValidateCustodyTransfer(publisher).validateGetTransferToken(em, keyBag);

                        int transferExpirationDays = DEFAULT_TRANSFEREXPIRATION_DAYS;
                        try {
                                transferExpirationDays = AppConfig.getConfiguration().getInt(Property.JUDDI_TRANSFER_EXPIRATION_DAYS);
                                // For output
                                nodeID.value = AppConfig.getConfiguration().getString(Property.JUDDI_NODE_ID);
                        } catch (ConfigurationException ce) {
                                throw new FatalErrorException(new ErrorMessage("errors.configuration.Retrieval"));
                        }

                        String transferKey = TRANSFER_TOKEN_PREFIX + UUID.randomUUID();
                        org.apache.juddi.model.TransferToken transferToken = new org.apache.juddi.model.TransferToken();
                        transferToken.setTransferToken(transferKey);
                        try {
                            // For output
                            opaqueToken.value = transferKey.getBytes(UTF8);
                        } catch (UnsupportedEncodingException ex) {
                            throw new InvalidValueException(new ErrorMessage("errors.stringEncoding"));
                        }

                        GregorianCalendar gc = new GregorianCalendar();
                        gc.add(GregorianCalendar.DAY_OF_MONTH, transferExpirationDays);

                        transferToken.setExpirationDate(gc.getTime());

                        try {
                                DatatypeFactory df = DatatypeFactory.newInstance();
                                // For output
                                expirationTime.value = df.newXMLGregorianCalendar(gc);
                        } catch (DatatypeConfigurationException ce) {
                                throw new FatalErrorException(new ErrorMessage("errors.Unspecified"));
                        }

                        List<String> keyList = keyBag.getKey();
                        for (String key : keyList) {
                                TransferTokenKey tokenKey = new TransferTokenKey(transferToken, key);
                                transferToken.getTransferKeys().add(tokenKey);
                        }

                        em.persist(transferToken);

                        tx.commit();

                        long procTime = System.currentTimeMillis() - startTime;
                        serviceCounter.update(CustodyTransferQuery.GET_TRANSFERTOKEN,
                                QueryStatus.SUCCESS, procTime);

                } finally {
                        if (tx.isActive()) {
                                tx.rollback();
                        }
                        em.close();
                }
        }

        @Override
        public void transferEntities(TransferEntities body)
                throws DispositionReportFaultMessage {
                long startTime = System.currentTimeMillis();

                EntityManager em = PersistenceManager.getEntityManager();
                EntityTransaction tx = em.getTransaction();
                List<ChangeRecord> changes = new ArrayList<ChangeRecord>();
                try {
                        tx.begin();

                        UddiEntityPublisher publisher = this.getEntityPublisher(em, body.getAuthInfo());

                        ValidateCustodyTransfer verifier = new ValidateCustodyTransfer(publisher);

                        //if the destination transfer is to a different node, 
                        if (!verifier.validateTransferEntities(em, body)) {
                                //i don't own these entities, so tell the owner to transfer to me.

                                //look up the replication config endpoint for that node and trigger the transfer, then return
                                //ok this is a node to node transfer, first up a replication client to the destination node
                                String sourceNode = null;
                                try {
                                        KeyBag keyBag = body.getKeyBag();
                                        List<String> keyList = keyBag.getKey();
                                        for (String key : keyList) {
                                                UddiEntity uddiEntity = em.find(UddiEntity.class, key);
                                                
                                                if (uddiEntity!=null) {
                                                        uddiEntity.setIsTransferInProgress(true);
                                                        sourceNode = uddiEntity.getNodeId();
                                                        em.merge(uddiEntity);
                                                        //save the fact we are expecting a transfer
                                                }
                                                else
                                                {
                                                        logger.warn("couldn't find a record for key " + key);
                                                }
                                        }
                                        if (sourceNode==null){
                                                logger.warn("unable to process transfer, could not locate the source node, perhaps it hasn't been replicated to this node yet?")
                                                        ;
                                                throw new Exception("unable to process transfer, could not locate the source node for any of the specific keys, perhaps it hasn't been replicated to this node yet?");
                                        }

                                        UDDIReplicationPortType replicationClient = getReplicationClient(sourceNode);
                                        if (replicationClient == null) {
                                                throw new Exception("Unknown node. is it in the replication graph?" + sourceNode);
                                        }
                                        TransferCustody transferCustody = new TransferCustody();
                                        transferCustody.setTransferToken(body.getTransferToken());
                                        transferCustody.setKeyBag(body.getKeyBag());
                                        transferCustody.setTransferOperationalInfo(new TransferOperationalInfo());
                                        transferCustody.getTransferOperationalInfo().setAuthorizedName(publisher.getAuthorizedName());
                                        transferCustody.getTransferOperationalInfo().setNodeID(getNode());

                                        //and trigger the transfer
                                        logger.info("AUDIT, transfering " + transferCustody.getKeyBag().getKey().size() + " entities to " + publisher.getAuthorizedName() + " at node " + getNode() + " from source " + sourceNode);
                                        replicationClient.transferCustody(transferCustody);
                                } catch (DispositionReportFaultMessage df) {
                                        logger.error("Unable to transfer entities from " + sourceNode + " to node " + getNode() + " to user " + publisher.getAuthorizedName(), df);
                                        throw new TransferNotAllowedException(new ErrorMessage("E_transferBlocked", df.getMessage()));
                                } catch (Exception ex) {
                                        logger.error("Unable to transfer entities from " + sourceNode + " to node " + getNode() + " to user " + publisher.getAuthorizedName(), ex);
                                        throw new TransferNotAllowedException(new ErrorMessage("E_transferBlocked", ex.getMessage()));
                                }

                        } else {
                                changes.addAll(executeTransfer(body, em, publisher.getAuthorizedName(), getNode()));
                                //all of the items to be transfer are owned locally by *this node.

                        }
                        tx.commit();
                        //we need to do something for replication purposes here
                        //enqueue notifications and storage of the changed records
                        for (ChangeRecord c : changes) {
                                try {
                                        c.setChangeID(new ChangeRecordIDType());
                                        c.getChangeID().setNodeID(getNode());
                                        c.getChangeID().setOriginatingUSN(null);
                                        ReplicationNotifier.enqueue(MappingApiToModel.mapChangeRecord(c));
                                } catch (UnsupportedEncodingException ex) {
                                        logger.error("", ex);
                                }
                        }
                        long procTime = System.currentTimeMillis() - startTime;
                        serviceCounter.update(CustodyTransferQuery.TRANSFER_ENTITIES,
                                QueryStatus.SUCCESS, procTime);

                } finally {
                        if (tx.isActive()) {
                                tx.rollback();
                        }
                        em.close();
                }

        }

        private synchronized UDDIReplicationPortType getReplicationClient(String node) {

                UDDIService svc = new UDDIService();
                UDDIReplicationPortType replicationClient = svc.getUDDIReplicationPort();

                EntityManager em = PersistenceManager.getEntityManager();
                EntityTransaction tx = em.getTransaction();
                try {
                        StringBuilder sql = new StringBuilder();
                        sql.append("select c from ReplicationConfiguration c order by c.serialNumber desc");
                        sql.toString();
                        Query qry = em.createQuery(sql.toString());
                        qry.setMaxResults(1);

                        org.apache.juddi.model.ReplicationConfiguration resultList = (org.apache.juddi.model.ReplicationConfiguration) qry.getSingleResult();
                        for (Operator o : resultList.getOperator()) {
                                if (o.getOperatorNodeID().equalsIgnoreCase(node)) {
                                        ((BindingProvider) replicationClient).getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, o.getSoapReplicationURL());

                                        return replicationClient;
                                }
                        }
                        tx.rollback();

                } catch (Exception ex) {
                        logger.fatal("Node not found (or there isn't a replication config)!" + node, ex);
                } finally {
                        if (tx.isActive()) {
                                tx.rollback();
                        }
                        em.close();
                }
                //em.close();
                return null;

        }

        /**
         * used to factor out the actual execution of custody transfer, used by
         * both this service and the replication service.
         *
         * @since 3.3
         * @param body
         * @param em
         * @param transferToPublisher
         * @param transferToNode
         * @return
         * @throws DispositionReportFaultMessage
         */
        protected List<ChangeRecord> executeTransfer(TransferEntities body, EntityManager em, String transferToPublisher, String transferToNode) throws DispositionReportFaultMessage {
                // Once validated, the ownership transfer is as simple as switching the publisher
                List<ChangeRecord> changes = new ArrayList<ChangeRecord>();;
                KeyBag keyBag = body.getKeyBag();
                List<String> keyList = keyBag.getKey();
                //used for the change journal

                for (String key : keyList) {
                        UddiEntity uddiEntity = em.find(UddiEntity.class, key);
                        uddiEntity.setAuthorizedName(transferToPublisher);
                        uddiEntity.setNodeId(transferToNode);
                        Date now = new Date();
                        uddiEntity.setModified(now);
                        uddiEntity.setModifiedIncludingChildren(now);

                        if (uddiEntity instanceof BusinessEntity) {
                                BusinessEntity be = (BusinessEntity) uddiEntity;

                                List<BusinessService> bsList = be.getBusinessServices();
                                for (BusinessService bs : bsList) {
                                        bs.setAuthorizedName(transferToPublisher);
                                        bs.setNodeId(transferToNode);
                                        bs.setModified(now);
                                        bs.setModifiedIncludingChildren(now);

                                        List<BindingTemplate> btList = bs.getBindingTemplates();
                                        for (BindingTemplate bt : btList) {
                                                bt.setAuthorizedName(transferToPublisher);
                                                bt.setNodeId(transferToNode);
                                                bt.setModified(now);
                                                bt.setModifiedIncludingChildren(now);

                                        }
                                }
                        }
                        ChangeRecord cr = new ChangeRecord();
                        cr.setChangeRecordNewData(new ChangeRecordNewData());
                        cr.getChangeRecordNewData().setOperationalInfo(new OperationalInfo());
                        cr.getChangeRecordNewData().getOperationalInfo().setAuthorizedName(transferToPublisher);
                        cr.getChangeRecordNewData().getOperationalInfo().setEntityKey(uddiEntity.getEntityKey());
                        cr.getChangeRecordNewData().getOperationalInfo().setNodeID(transferToNode);
                        GregorianCalendar gcal = new GregorianCalendar();
                        gcal.setTime(uddiEntity.getCreated());
                        cr.getChangeRecordNewData().getOperationalInfo().setCreated(df.newXMLGregorianCalendar(gcal));
                        gcal = new GregorianCalendar();
                        gcal.setTime(now);
                        cr.getChangeRecordNewData().getOperationalInfo().setModified(df.newXMLGregorianCalendar(gcal));
                        cr.getChangeRecordNewData().getOperationalInfo().setModifiedIncludingChildren(df.newXMLGregorianCalendar(gcal));
                        cr.getChangeRecordNewData().getOperationalInfo().setEntityKey(uddiEntity.getEntityKey());

                        if (uddiEntity instanceof BusinessEntity) {
                                cr.getChangeRecordNewData().setBusinessEntity(new org.uddi.api_v3.BusinessEntity());
                                MappingModelToApi.mapBusinessEntity((BusinessEntity) uddiEntity, cr.getChangeRecordNewData().getBusinessEntity());
                        }
                        if (uddiEntity instanceof Tmodel) {
                                cr.getChangeRecordNewData().setTModel(new org.uddi.api_v3.TModel());
                                MappingModelToApi.mapTModel((Tmodel) uddiEntity, cr.getChangeRecordNewData().getTModel());
                        }
                        changes.add(cr);
                        em.persist(uddiEntity);

                }

                // After transfer is finished, the token can be removed
                org.uddi.custody_v3.TransferToken apiTransferToken = body.getTransferToken();
                String transferTokenId;
                try {
                    transferTokenId = new String(apiTransferToken.getOpaqueToken(), UTF8);
                } catch (UnsupportedEncodingException ex) {
                    throw new InvalidValueException(new ErrorMessage("errors.stringEncoding"));
                }
                org.apache.juddi.model.TransferToken modelTransferToken = em.find(org.apache.juddi.model.TransferToken.class, transferTokenId);
                em.remove(modelTransferToken);
                return changes;
        }
}
