/*
 * JBoss, Home of Professional Open Source
 * Copyright 2006, Red Hat Middleware LLC, and individual contributors
 * by the @authors tag. See the copyright.txt in the distribution for a
 * full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package org.jboss.profileservice.spi;

import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Set;

import org.jboss.deployers.spi.attachments.Attachments;
import org.jboss.deployers.vfs.spi.client.VFSDeployment;
import org.jboss.managed.api.ManagedComponent;
import org.jboss.managed.api.ManagedDeployment.DeploymentPhase;
import org.jboss.virtual.VirtualFile;

/**
 * An interface for managing the contents of a Profile.
 * 
 * @author Scott.Stark@jboss.org
 * @author adrian@jboss.org
 * @version $Revision: 81408 $
 */
public interface DeploymentRepository
{
   /**
    * Get the admin attachments root path 
    * @return path to the root directory for attachments
    */
   public String getAttachmentsRoot();
   /**
    * Set the admin attachments root path
    * @param root - path to the root directory for attachments
    */
   public void setAttachmentsRoot(String root);

   /**
    * Create the repository
    * @throws Exception
    */
   public void create() throws Exception;
   /**
    * Load the repository contents
    * @throws Exception
    */
   public void load() throws Exception;
   /**
    * Delete the repository
    * @throws Exception
    */
   public void remove() throws Exception;
   /**
    * Get the time any contents were last modified
    * @return
    */
   public long getLastModified();

   /**
    * Get the URI of the root of deployments for the given phase.
    * @param phase - the phase of deployment
    * @return URI of the root of deployments for the given phase.
    */
   public URI getDeploymentURI(DeploymentPhase phase);
   /**
    * Get the URI of the root of deployments for the given phase.
    * @param phase - the phase of deployment
    * @param uri - URI of the root of deployments
    */
   public void setDeploymentURI(URI uri, DeploymentPhase phase);

   /**
    * Get the names of all deployments in the repository
    * @return
    */
   public Set<String> getDeploymentNames();
   /**
    * Get the names of all deployments in the repository for the
    * given phase.
    * @param phase - the phase of deployment
    * @return names of all deployments
    */
   public Set<String> getDeploymentNames(DeploymentPhase phase);


   /**
    * Upload raw deployment content to a profile repository. This does not make
    * the deployment avaialble to
    * @param vfsPath - the vfs path relative to the phase root
    * @param contentIS - the input stream for the deployment contents
    * @param phase - the phase of the deployment as it relates to when the
    *    deployment is loaded
    * @throws IOException
    * @return the unique name of the deployment in the repository
    */
   public String addDeploymentContent(String vfsPath, InputStream contentIS, DeploymentPhase phase)
      throws IOException;

   /**
    * Get repository names.
    *
    * @param names the names
    * @param phase the deployment phase
    * @return full repository names
    * @throws IOException for any error
    */
   public String[] getRepositoryNames(String[] names, DeploymentPhase phase)
      throws IOException;

   /**
    * Get the repository virtual file for the given deployment name
    * @param name - the unique virtual file URI name as returned by addDeploymentContent
    * @param phase - the phase of the deployment as it relates to when the deployment is loaded
    * @return the deployment content virtual file
    * @throws IOException for any error
    */
   public VirtualFile getDeploymentContent(String name, DeploymentPhase phase)
      throws IOException, URISyntaxException;

   /**
    * lock deployment content and exclude it from modified deployment checks.
    * @param vfsPath - the content vfs path relative to the deployment phase root
    * @param phase - the deployment phase
    * @return the deployment content flags, {@linkplain DeploymentContentFlags}
    */
   public int lockDeploymentContent(String vfsPath, DeploymentPhase phase);
   /**
    * Unlock a previously locked deployment content.
    * @param vfsPath - the content vfs path relative to the deployment phase root
    * @param phase - the deployment phase
    * @return the deployment content flags, {@linkplain DeploymentContentFlags}
    */
   public int unlockDeploymentContent(String vfsPath, DeploymentPhase phase);

   /**
    * Get the status flags for the deployment path
    * @param vfsPath - the content vfs path relative to the deployment phase root
    * @param phase - the deployment phase
    * @return the deployment content flags, {@linkplain DeploymentContentFlags}
    */
   public int getDeploymentContentFlags(String vfsPath, DeploymentPhase phase);
   /**
    * Set one or more flags for the deployment.
    * @see #clearDeploymentContentFlags(String, DeploymentPhase, int)
    * 
    * @param vfsPath - the content vfs path relative to the deployment phase root
    * @param phase - the deployment phase
    * @param flags - the deployment content flags, {@linkplain DeploymentContentFlags}
    */
   public int setDeploymentContentFlags(String vfsPath, DeploymentPhase phase,
         int flags);
   /**
    * Clear one or more flags for the deployment. This ands the compliment of
    * the flags argument into the existing content flags and returns the result.
    * 
    * @param vfsPath - the content vfs path relative to the deployment phase root
    * @param phase - the deployment phase
    * @param flags - the deployment content flags, {@linkplain DeploymentContentFlags}
    */
   public int clearDeploymentContentFlags(String vfsPath, DeploymentPhase phase,
         int flags);
   /**
    * Does a deployment content have the indicated flag.
    * 
    * @param vfsPath - the content vfs path relative to the deployment phase root
    * @param phase - the deployment phase
    * @param flags - the deployment content flags, {@linkplain DeploymentContentFlags}
    * @return true if the content flags contains the flag, false otherwise.
    */
   public boolean hasDeploymentContentFlags(String vfsPath, DeploymentPhase phase,
         int flag);

   /**
    * Acquire the repository write lock. This generally prevents content
    * uploads and {@link #getModifiedDeployments()} calls while the lock is
    * held.
    */
   public void acquireDeploymentContentLock();
   /**
    * Release the previously aquired repository write lock.
    */
   public void releaseDeploymentContentLock();

   /**
    * Add a deployment
    * 
    * @param vfsPath the path
    * @param d the deployment
    * @param phase - the phase of the deployment as it relates to when the
    * deployment is loaded
    * @throws Exception for any error
    */
   public void addDeployment(String vfsPath, VFSDeployment d, DeploymentPhase phase)
      throws Exception;
   /**
    * Update a deployments attachments. This persists the deployments
    * pre-determined attachments.
    * 
    * @param vfsPath - the vfs path relative to the phase root for the deployment
    * @param phase - the deployment phase
    * @param comp - the ManagedComponent that has been modified
    * @throws Exception
    */
   public void updateDeployment(VFSDeployment d, DeploymentPhase phase,
      ManagedComponent comp)
      throws Exception;

   /**
    * Get a named deployment.
    * 
    * @param name - the deployment name
    * @param phase - the phase of the deployment as it relates to when the
    * deployment is loaded
    * @return the named bootstrap
    * @throws NoSuchDeploymentException - if there is no such bootstrap
    * @throws IOException 
    * @throws Exception for any error
    */
   public VFSDeployment getDeployment(String name, DeploymentPhase phase)
      throws NoSuchDeploymentException, Exception;

   /**
    * Remove a deployment
    * 
    * @param vfsPath - the vfs path
    * @param phase - the phase of the deployment as it relates to when the
    * deployment is loaded
    * @return the removed deployment
    * @throws Exception for any error
    */
   public VFSDeployment removeDeployment(String vfsPath, DeploymentPhase phase)
      throws Exception;

   /**
    * Get all deployments for the given phase defined in this profile
    * 
    * @param phase - the phase of the deployment as it relates to when the
    * deployment is loaded
    * @return the bootstrap instances in this profile.
    * @throws Exception for any error
    */
   public Collection<VFSDeployment> getDeployments(DeploymentPhase phase)
      throws Exception;
   /**
    * Get all deployments defined in this profile
    * 
    * @return the deployment instances in this profile.
    * @throws Exception for any error
    */
   public Collection<VFSDeployment> getDeployments()
      throws Exception;

   public Collection<ModificationInfo> getModifiedDeployments()
      throws Exception;

   // Managed object attachments for a deployment
   public void addManagedObject(String vfsPath, Attachments edits)
      throws Exception;

}
