/*******************************************************************************
 * Copyright (c) 2004, 2007 Boeing.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Boeing - initial API and implementation
 *******************************************************************************/
package org.eclipse.osee.ote.messaging.dds.entity;

import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;
import org.eclipse.osee.framework.jdk.core.type.CompositeKeyHashMap;
import org.eclipse.osee.ote.messaging.dds.DataStoreItem;
import org.eclipse.osee.ote.messaging.dds.IDestination;
import org.eclipse.osee.ote.messaging.dds.ISource;
import org.eclipse.osee.ote.messaging.dds.NotImplementedException;
import org.eclipse.osee.ote.messaging.dds.ReturnCode;
import org.eclipse.osee.ote.messaging.dds.StatusKind;
import org.eclipse.osee.ote.messaging.dds.listener.DataWriterListener;
import org.eclipse.osee.ote.messaging.dds.listener.DomainParticipantListener;
import org.eclipse.osee.ote.messaging.dds.listener.Listener;
import org.eclipse.osee.ote.messaging.dds.listener.PublisherListener;
import org.eclipse.osee.ote.messaging.dds.listener.SubscriberListener;
import org.eclipse.osee.ote.messaging.dds.listener.TopicListener;
import org.eclipse.osee.ote.messaging.dds.service.DomainId;
import org.eclipse.osee.ote.messaging.dds.service.TopicDescription;
import org.eclipse.osee.ote.messaging.dds.service.TypeRegistry;
import org.eclipse.osee.ote.messaging.dds.service.TypeSignature;
import org.eclipse.osee.ote.messaging.dds.service.TypeSupport;

/**
 * Provides functionality for applications to participate within a domain as described in the DDS specification. The
 * DomainParticipant is a factory used by the application to create {@link Publisher}'s and {@link Subscriber}'s to
 * interact with the system.
 * <p>
 * In addition to the functionality described in the DDS specification, this class provides particular functionality to
 * interact with middleware which could be used to link this with another data system. The middleware is provided a
 * special publisher to inject data into this system, and receives data from all other publishers by means of the
 * {@link DomainParticipantListener}.
 * 
 * @author Robert A. Fisher
 * @author David Diepenbrock
 */
public class DomainParticipant extends Entity implements EntityFactory {
   private final DomainId domainId;
   // These collections REALLY need to be thread safe!!!
   private final CopyOnWriteArrayList<Publisher> publishers;
   private final CopyOnWriteArrayList<Subscriber> subscribers;
   private final CompositeKeyHashMap<String, String, Topic> topics;

   private final TypeRegistry typeRegistry;
   private Publisher middlewarePublisher; // Publisher who can send anything

   // DONT_NEED The builtinSubscriber is here for future functionality that is described in the DDS specification but has not been implemented or used.
   private final Subscriber builtinSubscriber;

   /**
    * @param domainId The domain this participant will belong to
    * @param domain A reference to the collection of all participants in this domain.
    * @param enabled Flag which indicates if this is enabled.
    * @param listener The listener attached to this.
    * @param parentFactory A reference to the factory that is creating this.
    * @param threadedPublishing <code>True</code> if we should create a separate thread for processing published data.
    * If <code>False</code>, the published data will be processed within the thread which makes the call to write data
    * into the system (or resume publications).
    * @param typeCapacity The initial capacity to use when creating the <code>Map</code> for the {@link TypeRegistry}.
    * @param typeFactor The load factor to use when creating the <code>Map</code> for the {@link TypeRegistry}.
    */
   DomainParticipant(DomainId domainId, Collection<DomainParticipant> domain, boolean enabled, DomainParticipantListener listener, EntityFactory parentFactory, boolean threadedPublishing, int typeCapacity, float typeFactor) {
      super(enabled, listener, parentFactory);

      this.domainId = domainId;
      this.publishers = new CopyOnWriteArrayList<>(); // Thread Safe
      this.subscribers = new CopyOnWriteArrayList<>(); // Thread Safe
      this.topics = new CompositeKeyHashMap<>(512, true);
      this.middlewarePublisher = null;
      this.typeRegistry = new TypeRegistry(typeCapacity, typeFactor);

      this.builtinSubscriber = null;
   }

   /**
    * Creates the DomainParticipant with default settings for typeCapacity and typeFactor.
    * 
    * @see DomainParticipant#DomainParticipant(DomainId, Collection, boolean, DomainParticipantListener, EntityFactory,
    * boolean, int, float)
    */
   DomainParticipant(DomainId domainId, Collection<DomainParticipant> domain, boolean enabled, DomainParticipantListener listener, EntityFactory parentFactory, boolean threadedPublishing) {
      this(domainId, domain, enabled, listener, parentFactory, threadedPublishing, 256, .75f);
   }

   /**
    * This method is here for future functionality that is described in the DDS specification but has not been
    * implemented or used.
    * 
    * @return Returns the builtinSubscriber.
    */
   public Subscriber getBuiltinSubscriber() {
      // DONT_NEED This method has not been implemented, but is called out in the spec
      if (true) {
         throw new NotImplementedException();
      }
      return builtinSubscriber;
   }

   /**
    * Gets the listener attached to this <code>DomainParticipant</code>.
    */
   public DomainParticipantListener getListener() {
      return (DomainParticipantListener) super.getBaseListener();
   }

   /**
    * Sets the listener attached to this <code>DomainParticipant</code>. This replaces the existing listener.
    * 
    * @param listener The listener to attach.
    * @param mask A mask identifying which communication statuses the listener should be invoked.
    * @return The {@link ReturnCode}returned by {@link Entity#setBaseListener(Listener, StatusKind)}.
    * @see Entity#setBaseListener(Listener, StatusKind)
    */
   public ReturnCode setListener(DomainParticipantListener listener, StatusKind mask) {
      return super.setBaseListener(listener, mask);
   }

   /**
    * Creates a publisher with the passed listener attached.
    * 
    * @param publisherListener The listener to attach to the newly created Publisher.
    * @return The newly created publisher, or null if an error occurred in creation.
    */
   private Publisher createAPublisher(PublisherListener publisherListener) {
      Publisher publisher = null;
      try {
         publisher = new Publisher(this, this.isEnabled(), publisherListener);
         publishers.add(publisher);
      } catch (OutOfMemoryError er) {
         er.printStackTrace();
         publisher = null;
      }

      return publisher;
   }

   /**
    * Creates a middlewarePublisher. If a middlewarePublisher has already been created this will return a reference to
    * the existing middlewarePublisher. The middlewarePublisher is provided as a link for an outside system to be able
    * to inject data into this system.
    * 
    * @param publisherListener The listener to attach to the newly created <code>Publisher</code>. Note that this can be
    * null.
    * @return A <code>Publisher</code> with the passed in listener assigned to it, or null if an error occurred in
    * creation.
    */
   public Publisher getMiddlewarePublisherInstance(PublisherListener publisherListener) {
      if (middlewarePublisher == null) {
         middlewarePublisher = createAPublisher(publisherListener);
      }
      return middlewarePublisher;
   }

   /**
    * Creates a new <code>Publisher</code> with a particular listener assigned to it. The publisher will be created
    * enabled iff this <code>DomainParticipant</code> is enabled. If an OutOfMemoryError is thrown while attempting get
    * the new publisher, <b>null </b> will be returned.
    * 
    * @param publisherListener The listener to be attached.
    * @return The newly created <code>Publisher</code>, or null if an error occurred in creation.
    */
   public Publisher createPublisher(PublisherListener publisherListener) {
      Publisher publisher = createAPublisher(publisherListener);
      if (publisher != null) {
         publishers.add(publisher);
      }
      return publisher;
   }

   /**
    * Removes the passed <code>Publisher</code> iff the publisher was created by this <code>DomainParticipant</code> and
    * does not have any attached <code>DataWriter</code> 's.
    * 
    * @param publisher The publisher to be removed.
    * @return {@link ReturnCode#OK}if the publisher was successfully removed, {@link ReturnCode#PRECONDITION_NOT_MET}if
    * the publisher had writers or was not created by this DomainParticipant, or {@link ReturnCode#ERROR}.
    */
   public ReturnCode deletePublisher(Publisher publisher) {

      // Check that the Entity is enabled before proceeding (See description of enable on the Entity object in the DDS spec)
      if (!isEnabled()) {
         return ReturnCode.NOT_ENABLED;
      }

      // Check that a publisher was supplied
      if (publisher == null) {
         return ReturnCode.ERROR;
      }

      // Check the pre-condition
      if (publisher.hasDataWriters()) {
         return ReturnCode.PRECONDITION_NOT_MET;
      }

      // Attempt to remove, if it did not exist in our list then return an error,
      // since it can only be removed from the <code>DomainParticipant</code> which created it.
      if (publishers.remove(publisher)) {
         return ReturnCode.OK;
      } else {
         return ReturnCode.PRECONDITION_NOT_MET;
      }
   }

   /**
    * Creates a <code>Subscriber</code> with the provided listener attached.
    * 
    * @param subscriberListener The listener to be attached.
    * @return The newly created <code>Subscriber</code>, or null if an error occurred in creation.
    */
   public Subscriber createSubscriber(SubscriberListener subscriberListener) {
      Subscriber subscriber = null;
      try {
         subscriber = new Subscriber(this, this.isEnabled(), subscriberListener);
         subscribers.add(subscriber);
      } catch (OutOfMemoryError er) {
         er.printStackTrace();
         subscriber = null;
      }
      return subscriber;
   }

   /**
    * Removes the passed <code>Subscriber</code> iff the subscriber was created by this <code>DomainParticipant</code>
    * and does not have any attached <code>DataReader</code> 's.
    * 
    * @param subscriber The subscriber to be removed.
    * @return {@link ReturnCode#OK}if the subscriber was successfully removed, {@link ReturnCode#PRECONDITION_NOT_MET}if
    * the subscriber had readers or was not created by this DomainParticipant, or {@link ReturnCode#ERROR}.
    */
   public ReturnCode deleteSubscriber(Subscriber subscriber) {

      // Check that the Entity is enabled before proceeding (See description of enable on the Entity object in the DDS spec)
      if (!isEnabled()) {
         return ReturnCode.NOT_ENABLED;
      }

      // Check that a subscriber was supplied
      if (subscriber == null) {
         return ReturnCode.ERROR;
      }

      // Check the pre-condition
      if (subscriber.hasDataReaders()) {
         return ReturnCode.PRECONDITION_NOT_MET;
      }

      // Attempt to remove, if it did not exist in our list then return an error,
      // since it can only be removed from the <code>DomainParticipant</code> which created it.
      if (subscribers.remove(subscriber)) {
         return ReturnCode.OK;
      } else {
         return ReturnCode.PRECONDITION_NOT_MET;
      }
   }

   /**
    * Creates a <code>Topic</code> on this <code>DomainParticipant</code> with the give name. If a <code>Topic</code>
    * already exists with the given name, then the existing topic will be returned IF the typeName matches that of the
    * existing <code>Topic</code>. If the type's do not match, <b>null </b> is returned.
    * 
    * @param name The name of the topic to create.
    * @param typeName The name of the type associated with the topic.
    * @param topicListener The listener to be attached to the created topic if it is newly created. If the topic already
    * exists, the provided listener is ignored.
    * @return A new <code>Topic</code> if one does not already exist, or an existing topic with the same
    * <code>name</code> and <code>typeName</code>, otherwise <b>null </b>
    */
   public Topic createTopic(String name, String namespace, String typeName, TopicListener topicListener) {

      Topic topic = null;

      // Even before that, check that the type was registered
      TypeSignature typeSignature = typeRegistry.lookupSignature(typeName);
      if (typeSignature == null) {
         throw new RuntimeException(String.format("No type signature with name [%s] was found.", typeName));
      } else {

         // First check to see if the topic already exists
         TopicDescription topicDescription = lookupTopicDescription(namespace, name);
         if (topicDescription != null && topicDescription instanceof Topic) {

            topic = (Topic) topicDescription;

            // Make sure that the type name is the same, otherwise it is failure
            if (topic.getTypeName().equals(typeName)) {
               // Track that another create has been called for this topic
               topic.incrementCount();
            } else {
               // There is a violation, and no topic will be returned since a topic
               // with this name already exists, but the types do not match
               throw new RuntimeException(
                  String.format(
                     "found topic name:[%s] namespace:[%s] but there was a type incompatibility between [%s] (from topic [%s]) and [%s].",
                     name, namespace, topic.getTypeName(), topic.getName(), typeName));
            }
         } else { // Otherwise, the topic did not already exist
            topic = new Topic(this, typeSignature, name, namespace, this.isEnabled(), topicListener, this);
            topics.put(namespace, name, topic);
         }
      }
      return topic;
   }

   /**
    * This method deletes a <code>Topic</code> previously created by this <code>DomainParticipant</code>. No action will
    * be taken if the topic still has data readers/writers attached to it, or if it was not created by this
    * <code>DomainParticipant</code>.
    * 
    * @param topic The topic to delete.
    * @return {@link ReturnCode#OK}if the topic was successfully removed, {@link ReturnCode#PRECONDITION_NOT_MET}if the
    * topic has readers/writers or was not created by this DomainParticipant, {@link ReturnCode#NOT_ENABLED}if this
    * DomainParticipant is not enabled, or {@link ReturnCode#ERROR}.
    */
   public ReturnCode deleteTopic(Topic topic) {

      // Check that the Entity is enabled before proceeding (See description of enable on the Entity object in the DDS spec)
      if (!isEnabled()) {
         return ReturnCode.NOT_ENABLED;
      }

      // Check the pre-condition
      if (topic.hasDataReaders()) {
         return ReturnCode.PRECONDITION_NOT_MET;
      }
      // Check the pre-condition
      if (topic.hasDataWriters()) {
         return ReturnCode.PRECONDITION_NOT_MET;
      }

      // Check that a topic was supplied
      if (topic == null) {
         return ReturnCode.ERROR;
      }

      // Attempt to remove, if it did not exist in our list then return an error,
      // since it can only be removed from the <code>DomainParticipant</code> which created it.
      if (topics.containsKey(topic.getNamespace() + topic.getName())) {
         // Reduce the count of creations by 1
         topic.decrementCount();

         // If the creation count is zero, then remove it from the list
         if (topic.getCount() <= 0) {
            topics.removeValues(topic.getNamespace() + topic.getName());
         }

         return ReturnCode.OK;
      } else {
         return ReturnCode.PRECONDITION_NOT_MET;
      }
   }

   /**
    * Get a <code>TopicDescription</code> that matches a particular name. PARTIAL: Since the
    * <code>ContentFilteredTopic</code> and <code>MultiTopic</code> classes are not implemented, this method simply
    * searches the list of <code>Topic</code> classes.
    * 
    * @param namespace The name to match against the <code>TopicDescription</code>.
    * @return The <code>TopicDescription</code> that has the specified name, <b>null </b> if no such one exists.
    */
   public TopicDescription lookupTopicDescription(String namespace, String topic) {
      //PARTIAL ContentFilteredTopic and MultiTopic are not implemented, so this only searches Topic.
      return findTopicByName(namespace, topic);
   }

   /**
    * Searches the current list of Topics for this DomainParticipant for a topic whose name matches the provided
    * topicName
    * 
    * @param topicName The topic name to match
    * @return A reference to the existing topic whose name matches topicName, or null if no such topic exists.
    */
   private Topic findTopicByName(String namespace, String topicName) {
      return topics.get(namespace, topicName);
   }

   /**
    * This method is here for future functionality that is described in the DDS specification but has not been
    * implemented or used.
    * 
    * @return {@link ReturnCode#OK}if the participant was successfully set to be ignored, {@link ReturnCode#NOT_ENABLED}
    * if this DomainParticipant is not enabled, or {@link ReturnCode#ERROR}.
    */
   public ReturnCode ignoreParticipant() {
      // UNSURE this is stubbed for now, until we determine it's necessity

      // Check that the Entity is enabled before proceeding (See description of enable on the Entity object in the DDS spec)
      if (!isEnabled()) {
         return ReturnCode.NOT_ENABLED;
      }

      return ReturnCode.ERROR;
   }

   /**
    * This method is here for future functionality that is described in the DDS specification but has not been
    * implemented or used.
    * 
    * @return {@link ReturnCode#OK}if the topic was successfully set to be ignored, {@link ReturnCode#NOT_ENABLED}if
    * this DomainParticipant is not enabled, or {@link ReturnCode#ERROR}.
    */
   public ReturnCode ignoreTopic() {
      // UNSURE This method has not been implemented, but is called out in the spec
      if (true) {
         throw new NotImplementedException();
      }

      // Check that the Entity is enabled before proceeding (See description of enable on the Entity object in the DDS spec)
      if (!isEnabled()) {
         return ReturnCode.NOT_ENABLED;
      }

      return ReturnCode.ERROR;
   }

   /**
    * This method is here for future functionality that is described in the DDS specification but has not been
    * implemented or used.
    * 
    * @return {@link ReturnCode#OK}if the publication was successfully set to be ignored, {@link ReturnCode#NOT_ENABLED}
    * if this DomainParticipant is not enabled, or {@link ReturnCode#ERROR}.
    */
   public ReturnCode ignorePublication() {
      // UNSURE This method has not been implemented, but is called out in the spec
      if (true) {
         throw new NotImplementedException();
      }

      // Check that the Entity is enabled before proceeding (See description of enable on the Entity object in the DDS spec)
      if (!isEnabled()) {
         return ReturnCode.NOT_ENABLED;
      }

      return ReturnCode.ERROR;
   }

   /**
    * This method is here for future functionality that is described in the DDS specification but has not been
    * implemented or used.
    * 
    * @return {@link ReturnCode#OK}if the subscription was successfully set to be ignored,
    * {@link ReturnCode#NOT_ENABLED}if this DomainParticipant is not enabled, or {@link ReturnCode#ERROR}.
    */
   public ReturnCode ignoreSubscription() {
      // UNSURE This method has not been implemented, but is called out in the spec
      if (true) {
         throw new NotImplementedException();
      }

      // Check that the Entity is enabled before proceeding (See description of enable on the Entity object in the DDS spec)
      if (!isEnabled()) {
         return ReturnCode.NOT_ENABLED;
      }

      return ReturnCode.ERROR;
   }

   /**
    * Gets the <code>DomainId</code> that this <code>DomainParticipant</code> belongs to.
    * 
    * @return The <code>DomainId</code> of this participant.
    */
   public DomainId getDomainId() {
      return domainId;
   }

   /**
    * Performs a deep deletion of contained entities (Publishers, Subscribers, Topics). This will cause a recursive call
    * of <code>deleteContainedEntities</code> through out all of the contained entities. This can only be performed if
    * the <code>DomainParticipant</code> is enabled.
    * 
    * @return {@link ReturnCode#OK}if the all entities were successfully deleted, or {@link ReturnCode#NOT_ENABLED}if
    * this DomainParticipant is not enabled.
    */
   public ReturnCode deleteContainedEntities() {

      // Check that the Entity is enabled before proceeding (See description of enable on the Entity object in the DDS spec)
      if (!isEnabled()) {
         return ReturnCode.NOT_ENABLED;
      }

      for (Publisher publisher : publishers) {
         publisher.deleteContainedEntities();
      }
      publishers.clear();

      for (Subscriber subscriber : subscribers) {
         subscriber.deleteContainedEntities();
      }

      subscribers.clear();

      this.middlewarePublisher = null;

      // Topics do not contain anything else
      topics.clear();

      return ReturnCode.OK;
   }

   /**
    * This method is here for future functionality that is described in the DDS specification but has not been
    * implemented or used.
    */
   public void assertLiveliness() {
      // UNSURE This method has not been implemented, but is called out in the spec
      if (true) {
         throw new NotImplementedException();
      }
   }

   /**
    * Returns true iff this <code>DomainParticipant</code> contains at least one publisher, subscriber or topic.
    * 
    * @return <b>true </b> if this contains an entity, <b>false </b> otherwise.
    */
   public boolean hasEntities() {
      return !(publishers.isEmpty() && subscribers.isEmpty() && topics.isEmpty());
   }

   /**
    * Propagates the published data to each <code>Subscriber</code> of this <code>DomainParticipant</code>. Notifies the
    * middleware (by means of the {@link DomainParticipantListener}of the new data unless it originated from the
    * middlewarePublisher. The middleware is only notified of data originating from this <code>DomainPariticipant</code>
    * , that is, data published from other participants in the domain will not be sent to the middleware.
    * 
    * @param destination TODO
    * @param source TODO
    * @param dataStoreItem The <code>DataStoreItem</code> that was published.
    */
   void processPublishedData(IDestination destination, ISource source, DataStoreItem dataStoreItem) { // package scope since it is a
      // system-level call

      // Notify the middleware of new data, unless it was published by the middlewarePublisher
      // When data is published by the middlewarePublisher it does not have an associated DataWriter

      DataWriter writer = dataStoreItem.getTheWriter();
      if (writer != null) {
         // Invoke the DomainParticipantListener if available
         DomainParticipantListener domainParticipantListener = getListener();
         if (domainParticipantListener != null) {
            domainParticipantListener.onPublishNotifyMiddleware(destination, source, dataStoreItem);
         }

         // If the writer has a listener, then invoke it
         DataWriterListener writerListener = writer.getListener();
         if (writerListener != null) {
            writerListener.onDataSentToMiddleware(writer);
         }

      }

      if (writer == null || writer != null && writer.isPublishBackToLocalDDSReaders()) {
         // Notify all of the subscribers in our domain
         for (Subscriber domainSubscribers : subscribers) {
            domainSubscribers.processNewData(dataStoreItem);
         }
      }
   }

   /**
    * Gets the <code>TypeRegistry</code> used by {@link TypeSupport}to store the types registered for this
    * <code>DomainParticipant</code>.
    * 
    * @return Returns the typeRegistry.
    */
   public TypeRegistry getTypeRegistry() {
      return typeRegistry;
   }

   /**
    * Gets the Middleware <code>Publisher</code> if one has been created.
    * 
    * @return Returns the <code>Publisher</code> for the middleware, or null if it has not been created.
    * @see DomainParticipant
    */
   public Publisher getMiddlewarePublisher() {
      return middlewarePublisher;
   }

   /**
    * Gets the current <code>Collection</code> of <code>Publisher</code>'s for this <code>DomainPariticpant</code>.
    * 
    * @return Returns the <code>Collection</code> of <code>Publisher</code> 's.
    */
   public CopyOnWriteArrayList<Publisher> getPublishers() {
      return publishers;
   }

   public void dispose() {
      for (Topic topic : topics.values()) {
         topic.clearDataReaders();
         topic.clearDataWriters();
      }
      topics.clear();
      for (Subscriber subscriber : subscribers) {
         if (subscriber.deleteContainedEntities() == ReturnCode.NOT_ENABLED) {
            System.err.println("failed to delete subscriber because it was not enabled");
         }
      }
      subscribers.clear();

      for (Publisher publisher : publishers) {
         publisher.dispose();
      }
      publishers.clear();

      typeRegistry.clear();
   }
}
