/*
 *
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.qpid.server.model;

import java.security.AccessControlException;
import java.util.Collection;
import java.util.Date;
import java.util.Map;
import java.util.UUID;

import javax.security.auth.Subject;

import com.google.common.util.concurrent.ListenableFuture;

import org.apache.qpid.server.configuration.updater.TaskExecutor;
import org.apache.qpid.server.model.preferences.UserPreferences;
import org.apache.qpid.server.security.SecurityToken;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.store.ConfiguredObjectRecord;

@ManagedObject( creatable = false, category = false )
/**
 * An object that can be "managed" (eg via the web interface) and usually read from configuration.
 */
public interface ConfiguredObject<X extends ConfiguredObject<X>> extends ContextProvider, TaskExecutorProvider,
                                                                         PermissionedObject
{
    String OVER_SIZED_ATTRIBUTE_ALTERNATIVE_TEXT = "Value is too long to display";

    String ID = "id";
    String NAME = "name";
    String TYPE = "type";
    String DESCRIPTION = "description";
    String DURABLE = "durable";
    String CONTEXT = "context";
    String LIFETIME_POLICY = "lifetimePolicy";

    String LAST_UPDATED_BY = "lastUpdatedBy";
    String LAST_UPDATED_TIME = "lastUpdatedTime";
    String STATE = "state";
    String DESIRED_STATE = "desiredState";
    String CREATED_BY = "createdBy";
    String CREATED_TIME = "createdTime";


    String AWAIT_ATTAINMENT_TIMEOUT = "awaitAttainmentTimeout";
    @ManagedContextDefault( name = AWAIT_ATTAINMENT_TIMEOUT)
    public static final int DEFAULT_AWAIT_ATTAINMENT_TIMEOUT = 5000;

    /**
     * Get the universally unique identifier for the object
     *
     * @return the objects id
     */
    @ManagedAttribute( mandatory = true, immutable = true )
    UUID getId();

    /**
     * Get the name of the object
     *
     * @return the name of the object
     */
    @ManagedAttribute( mandatory = true )
    String getName();


    @ManagedAttribute
    String getDescription();

    @ManagedAttribute ( immutable = true )
    String getType();

    @ManagedAttribute
    Map<String, String> getContext();

    @DerivedAttribute( persist = true )
    String getLastUpdatedBy();

    @DerivedAttribute( persist = true )
    Date getLastUpdatedTime();

    @DerivedAttribute( persist = true )
    String getCreatedBy();

    @DerivedAttribute( persist = true )
    Date getCreatedTime();


    /**
     * Get the desired state of the object.
     *
     * This is the state set at the object itself, however the object
     * may not be able attain this state if one of its ancestors is in a different state (in particular a descendant
     * object may not be ACTIVE if all of its ancestors are not also ACTIVE).
     *
     * @return the desired state of the object
     */
    @ManagedAttribute( defaultValue = "ACTIVE" )
    State getDesiredState();

    /**
     * Get the actual state of the object.
     *
     * This state is derived from the desired state of the object itself and
     * the actual state of its parents. If an object "desires" to be ACTIVE, but one of its parents is STOPPED, then
     * the actual state of the object will be STOPPED
     *
     * @return the actual state of the object
     */
    @DerivedAttribute
    State getState();

    @DerivedAttribute
    Date getLastOpenedTime();

    /**
     * Add a listener which will be informed of all changes to this configuration object
     *
     * @param listener the listener to add
     */
    void addChangeListener(ConfigurationChangeListener listener);

    /**
     * Remove a change listener
     *
     *
     * @param listener the listener to remove
     * @return true iff a listener was removed
     */
    boolean removeChangeListener(ConfigurationChangeListener listener);

    /**
     * Get the parent of the given type for this object
     *
     * @param clazz the class of parent being asked for
     * @return the objects parent
     */
    <T extends ConfiguredObject> T getParent(Class<T> clazz);


    /**
     * Returns whether the the object configuration is durably stored
     *
     * @return the durability
     */
    @ManagedAttribute( defaultValue = "true", immutable = true)
    boolean isDurable();

    /**
     * Return the lifetime policy for the object
     *
     * @return the lifetime policy
     */
    @ManagedAttribute( defaultValue = "PERMANENT" )
    LifetimePolicy getLifetimePolicy();

    /**
     * Get the names of attributes that are set on this object
     *
     * Note that the returned collection is correct at the time the method is called, but will not reflect future
     * additions or removals when they occur
     *
     * @return the collection of attribute names
     */
    Collection<String> getAttributeNames();


    /**
     * Return the value for the given attribute name. The actual attribute value
     * is returned if the configured object has such attribute set. If not, the
     * value is looked default attributes.
     *
     * @param name
     *            the name of the attribute
     * @return the value of the attribute at the object (or null if the
     *         attribute value is set neither on object itself no in defaults)
     */
    Object getAttribute(String name);

    /**
     * Return the map containing only explicitly set attributes
     *
     * @return the map with the attributes
     */
    Map<String, Object> getActualAttributes();


    /**
     * Return the statistics for the ConfiguredObject
     *
     * @return the current statistics for the ConfiguredObject
     */
    Map<String, Object> getStatistics();

    /**
     * Return children of the ConfiguredObject of the given class
     *
     * @param clazz the class of the children to return
     * @return the children
     *
     * @throws NullPointerException if the supplied class null
     *
     */
    <C extends ConfiguredObject> Collection<C> getChildren(Class<C> clazz);

    <C extends ConfiguredObject> C getChildById(Class<C> clazz, UUID id);

    <C extends ConfiguredObject> C getChildByName(Class<C> clazz, String name);


    <C extends ConfiguredObject> C createChild(Class<C> childClass,
                                               Map<String, Object> attributes,
                                               ConfiguredObject... otherParents);

    <C extends ConfiguredObject> ListenableFuture<C> getAttainedChildById(Class<C> childClass,
                                                                          UUID id);

    <C extends ConfiguredObject> ListenableFuture<C> getAttainedChildByName(Class<C> childClass, String name);

    <C extends ConfiguredObject> ListenableFuture<C> createChildAsync(Class<C> childClass,
                                                                      Map<String, Object> attributes,
                                                                      ConfiguredObject... otherParents);

    void setAttributes(Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException;
    ListenableFuture<Void> setAttributesAsync(Map<String, Object> attributes) throws IllegalStateException, AccessControlException, IllegalArgumentException;


    Class<? extends ConfiguredObject> getCategoryClass();
    Class<? extends ConfiguredObject> getTypeClass();

    boolean managesChildStorage();

    <C extends ConfiguredObject<C>> C findConfiguredObject(Class<C> clazz, String name);

    // TODO - remove this when objects become responsible for their own storage
    ConfiguredObjectRecord asObjectRecord();

    void open();
    ListenableFuture<Void> openAsync();

    void close();
    ListenableFuture<Void> closeAsync();

    ListenableFuture<Void> deleteAsync();

    TaskExecutor getChildExecutor();

    ConfiguredObjectFactory getObjectFactory();

    Model getModel();

    void delete();

    boolean hasEncrypter();
    void decryptSecrets();

    UserPreferences getUserPreferences();
    void setUserPreferences(UserPreferences userPreferences);

    void authorise(Operation operation) throws AccessControlException;
    void authorise(Operation operation, Map<String, Object> arguments) throws AccessControlException;
    void authorise(SecurityToken token, Operation operation, Map<String, Object> arguments) throws AccessControlException;
    SecurityToken newToken(Subject subject);
}
