/*
 * CDDL HEADER START
 *
 * The contents of this file are subject to the terms of the
 * Common Development and Distribution License, Version 1.0 only
 * (the "License").  You may not use this file except in compliance
 * with the License.
 *
 * You can obtain a copy of the license at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE
 * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 *
 * When distributing Covered Code, include this CDDL HEADER in each
 * file and include the License file at
 * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
 * add the following below this CDDL HEADER, with the fields enclosed
 * by brackets "[]" replaced with your own identifying information:
 *      Portions Copyright [yyyy] [name of copyright owner]
 *
 * CDDL HEADER END
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 */
package org.opends.server.admin.std.meta;



import java.util.Collection;
import java.util.SortedSet;
import org.opends.server.admin.AdministratorAction;
import org.opends.server.admin.BooleanPropertyDefinition;
import org.opends.server.admin.client.AuthorizationException;
import org.opends.server.admin.client.CommunicationException;
import org.opends.server.admin.client.ConcurrentModificationException;
import org.opends.server.admin.client.ManagedObject;
import org.opends.server.admin.client.MissingMandatoryPropertiesException;
import org.opends.server.admin.client.OperationRejectedException;
import org.opends.server.admin.DefaultBehaviorProvider;
import org.opends.server.admin.DefinedDefaultBehaviorProvider;
import org.opends.server.admin.EnumPropertyDefinition;
import org.opends.server.admin.IPAddressMaskPropertyDefinition;
import org.opends.server.admin.ManagedObjectAlreadyExistsException;
import org.opends.server.admin.ManagedObjectDefinition;
import org.opends.server.admin.PropertyOption;
import org.opends.server.admin.PropertyProvider;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.server.ServerManagedObject;
import org.opends.server.admin.std.client.NetworkGroupCriteriaCfgClient;
import org.opends.server.admin.std.server.NetworkGroupCriteriaCfg;
import org.opends.server.admin.StringPropertyDefinition;
import org.opends.server.admin.Tag;
import org.opends.server.admin.TopCfgDefn;
import org.opends.server.admin.UndefinedDefaultBehaviorProvider;
import org.opends.server.types.AddressMask;
import org.opends.server.types.DN;



/**
 * An interface for querying the Network Group Criteria managed object
 * definition meta information.
 * <p>
 * The Network Group Criteria is used to classify incoming
 * connections.
 */
public final class NetworkGroupCriteriaCfgDefn extends ManagedObjectDefinition<NetworkGroupCriteriaCfgClient, NetworkGroupCriteriaCfg> {

  // The singleton configuration definition instance.
  private static final NetworkGroupCriteriaCfgDefn INSTANCE = new NetworkGroupCriteriaCfgDefn();



  /**
   * Defines the set of permissable values for the "allowed-auth-method" property.
   * <p>
   * Specifies the allowed authorization methods for a client
   * connection to match the Network Group Criteria.
   */
  public static enum AllowedAuthMethod {

    /**
     * Anonymous connections.
     */
    ANONYMOUS("anonymous"),



    /**
     * SASL/external connections, with a certificate containing the
     * user authentication.
     */
    SASL("sasl"),



    /**
     * Simple bind connections, with bind DN and password.
     */
    SIMPLE("simple");



    // String representation of the value.
    private final String name;



    // Private constructor.
    private AllowedAuthMethod(String name) { this.name = name; }



    /**
     * {@inheritDoc}
     */
    public String toString() { return name; }

  }



  /**
   * Defines the set of permissable values for the "allowed-ldap-port" property.
   * <p>
   * Specifies the allowed LDAP ports for the client connection to
   * match the Network Group Criteria.
   */
  public static enum AllowedLDAPPort {

    /**
     * Connection over ldap port.
     */
    LDAP("ldap"),



    /**
     * Connection over ldaps port.
     */
    LDAPS("ldaps");



    // String representation of the value.
    private final String name;



    // Private constructor.
    private AllowedLDAPPort(String name) { this.name = name; }



    /**
     * {@inheritDoc}
     */
    public String toString() { return name; }

  }



  // The "allowed-auth-method" property definition.
  private static final EnumPropertyDefinition<AllowedAuthMethod> PD_ALLOWED_AUTH_METHOD;



  // The "allowed-ldap-port" property definition.
  private static final EnumPropertyDefinition<AllowedLDAPPort> PD_ALLOWED_LDAP_PORT;



  // The "bind-dn-filter" property definition.
  private static final StringPropertyDefinition PD_BIND_DN_FILTER;



  // The "ip-address-filter" property definition.
  private static final IPAddressMaskPropertyDefinition PD_IP_ADDRESS_FILTER;



  // The "is-security-mandatory" property definition.
  private static final BooleanPropertyDefinition PD_IS_SECURITY_MANDATORY;



  // The "user-entry-filter" property definition.
  private static final StringPropertyDefinition PD_USER_ENTRY_FILTER;



  // Build the "allowed-auth-method" property definition.
  static {
      EnumPropertyDefinition.Builder<AllowedAuthMethod> builder = EnumPropertyDefinition.createBuilder(INSTANCE, "allowed-auth-method");
      builder.setOption(PropertyOption.MULTI_VALUED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "allowed-auth-method"));
      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<AllowedAuthMethod>());
      builder.setEnumClass(AllowedAuthMethod.class);
      PD_ALLOWED_AUTH_METHOD = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_ALLOWED_AUTH_METHOD);
  }



  // Build the "allowed-ldap-port" property definition.
  static {
      EnumPropertyDefinition.Builder<AllowedLDAPPort> builder = EnumPropertyDefinition.createBuilder(INSTANCE, "allowed-ldap-port");
      builder.setOption(PropertyOption.MULTI_VALUED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "allowed-ldap-port"));
      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<AllowedLDAPPort>());
      builder.setEnumClass(AllowedLDAPPort.class);
      PD_ALLOWED_LDAP_PORT = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_ALLOWED_LDAP_PORT);
  }



  // Build the "bind-dn-filter" property definition.
  static {
      StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "bind-dn-filter");
      builder.setOption(PropertyOption.MULTI_VALUED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "bind-dn-filter"));
      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>());
      PD_BIND_DN_FILTER = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_BIND_DN_FILTER);
  }



  // Build the "ip-address-filter" property definition.
  static {
      IPAddressMaskPropertyDefinition.Builder builder = IPAddressMaskPropertyDefinition.createBuilder(INSTANCE, "ip-address-filter");
      builder.setOption(PropertyOption.MULTI_VALUED);
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "ip-address-filter"));
      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<AddressMask>());
      PD_IP_ADDRESS_FILTER = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_IP_ADDRESS_FILTER);
  }



  // Build the "is-security-mandatory" property definition.
  static {
      BooleanPropertyDefinition.Builder builder = BooleanPropertyDefinition.createBuilder(INSTANCE, "is-security-mandatory");
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "is-security-mandatory"));
      DefaultBehaviorProvider<Boolean> provider = new DefinedDefaultBehaviorProvider<Boolean>("false");
      builder.setDefaultBehaviorProvider(provider);
      PD_IS_SECURITY_MANDATORY = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_IS_SECURITY_MANDATORY);
  }



  // Build the "user-entry-filter" property definition.
  static {
      StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "user-entry-filter");
      builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "user-entry-filter"));
      builder.setDefaultBehaviorProvider(new UndefinedDefaultBehaviorProvider<String>());
      PD_USER_ENTRY_FILTER = builder.getInstance();
      INSTANCE.registerPropertyDefinition(PD_USER_ENTRY_FILTER);
  }



  // Register the tags associated with this managed object definition.
  static {
    INSTANCE.registerTag(Tag.valueOf("core-server"));
  }



  /**
   * Get the Network Group Criteria configuration definition
   * singleton.
   *
   * @return Returns the Network Group Criteria configuration
   *         definition singleton.
   */
  public static NetworkGroupCriteriaCfgDefn getInstance() {
    return INSTANCE;
  }



  /**
   * Private constructor.
   */
  private NetworkGroupCriteriaCfgDefn() {
    super("network-group-criteria", TopCfgDefn.getInstance());
  }



  /**
   * {@inheritDoc}
   */
  public NetworkGroupCriteriaCfgClient createClientConfiguration(
      ManagedObject<? extends NetworkGroupCriteriaCfgClient> impl) {
    return new NetworkGroupCriteriaCfgClientImpl(impl);
  }



  /**
   * {@inheritDoc}
   */
  public NetworkGroupCriteriaCfg createServerConfiguration(
      ServerManagedObject<? extends NetworkGroupCriteriaCfg> impl) {
    return new NetworkGroupCriteriaCfgServerImpl(impl);
  }



  /**
   * {@inheritDoc}
   */
  public Class<NetworkGroupCriteriaCfg> getServerConfigurationClass() {
    return NetworkGroupCriteriaCfg.class;
  }



  /**
   * Get the "allowed-auth-method" property definition.
   * <p>
   * Specifies the allowed authorization methods for a client
   * connection to match the Network Group Criteria.
   *
   * @return Returns the "allowed-auth-method" property definition.
   */
  public EnumPropertyDefinition<AllowedAuthMethod> getAllowedAuthMethodPropertyDefinition() {
    return PD_ALLOWED_AUTH_METHOD;
  }



  /**
   * Get the "allowed-ldap-port" property definition.
   * <p>
   * Specifies the allowed LDAP ports for the client connection to
   * match the Network Group Criteria.
   *
   * @return Returns the "allowed-ldap-port" property definition.
   */
  public EnumPropertyDefinition<AllowedLDAPPort> getAllowedLDAPPortPropertyDefinition() {
    return PD_ALLOWED_LDAP_PORT;
  }



  /**
   * Get the "bind-dn-filter" property definition.
   * <p>
   * Specifies a bind DN filter for the client connection to match the
   * Network Group Criteria.
   * <p>
   * A valid bind DN filter is a string composed of zero or more
   * wildcards. A double wildcard ** replaces one or more RDN
   * components (as in uid=dmiller,**,dc=example,dc=com). A simple
   * wildcard * replaces either a whole RDN, or a whole type, or a
   * value substring (as in uid=bj*,ou=people,dc=example,dc=com).
   *
   * @return Returns the "bind-dn-filter" property definition.
   */
  public StringPropertyDefinition getBindDNFilterPropertyDefinition() {
    return PD_BIND_DN_FILTER;
  }



  /**
   * Get the "ip-address-filter" property definition.
   * <p>
   * Specifies an IP address filter for the Network Group Criteria.
   * <p>
   * A valid IP address mask can be one of the followings:
   * 129.34.55.67 129.*.78.55 .sun.com foo.sun.com foo.*.sun.*
   * 128.*.*.* 129.45.23.67/22 128.33.21.21/32 *.*.*.* 129.45.67.34/0
   * foo.com foo 2001:fecd:ba23:cd1f:dcb1:1010:9234:4088/124
   * 2001:fecd:ba23:cd1f:dcb1:1010:9234:4088
   * [2001:fecd:ba23:cd1f:dcb1:1010:9234:4088]/45 ::/128 ::1/128 ::
   *
   * @return Returns the "ip-address-filter" property definition.
   */
  public IPAddressMaskPropertyDefinition getIPAddressFilterPropertyDefinition() {
    return PD_IP_ADDRESS_FILTER;
  }



  /**
   * Get the "is-security-mandatory" property definition.
   * <p>
   * Specifies whether security is mandatory for the Network Group
   * Criteria.
   *
   * @return Returns the "is-security-mandatory" property definition.
   */
  public BooleanPropertyDefinition getIsSecurityMandatoryPropertyDefinition() {
    return PD_IS_SECURITY_MANDATORY;
  }



  /**
   * Get the "user-entry-filter" property definition.
   * <p>
   * Specifies a search filter that the entry of a bound client must
   * match.
   *
   * @return Returns the "user-entry-filter" property definition.
   */
  public StringPropertyDefinition getUserEntryFilterPropertyDefinition() {
    return PD_USER_ENTRY_FILTER;
  }



  /**
   * Managed object client implementation.
   */
  private static class NetworkGroupCriteriaCfgClientImpl implements
    NetworkGroupCriteriaCfgClient {

    // Private implementation.
    private ManagedObject<? extends NetworkGroupCriteriaCfgClient> impl;



    // Private constructor.
    private NetworkGroupCriteriaCfgClientImpl(
        ManagedObject<? extends NetworkGroupCriteriaCfgClient> impl) {
      this.impl = impl;
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<AllowedAuthMethod> getAllowedAuthMethod() {
      return impl.getPropertyValues(INSTANCE.getAllowedAuthMethodPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setAllowedAuthMethod(Collection<AllowedAuthMethod> values) {
      impl.setPropertyValues(INSTANCE.getAllowedAuthMethodPropertyDefinition(), values);
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<AllowedLDAPPort> getAllowedLDAPPort() {
      return impl.getPropertyValues(INSTANCE.getAllowedLDAPPortPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setAllowedLDAPPort(Collection<AllowedLDAPPort> values) {
      impl.setPropertyValues(INSTANCE.getAllowedLDAPPortPropertyDefinition(), values);
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<String> getBindDNFilter() {
      return impl.getPropertyValues(INSTANCE.getBindDNFilterPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setBindDNFilter(Collection<String> values) {
      impl.setPropertyValues(INSTANCE.getBindDNFilterPropertyDefinition(), values);
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<AddressMask> getIPAddressFilter() {
      return impl.getPropertyValues(INSTANCE.getIPAddressFilterPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setIPAddressFilter(Collection<AddressMask> values) {
      impl.setPropertyValues(INSTANCE.getIPAddressFilterPropertyDefinition(), values);
    }



    /**
     * {@inheritDoc}
     */
    public boolean isIsSecurityMandatory() {
      return impl.getPropertyValue(INSTANCE.getIsSecurityMandatoryPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setIsSecurityMandatory(Boolean value) {
      impl.setPropertyValue(INSTANCE.getIsSecurityMandatoryPropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public String getUserEntryFilter() {
      return impl.getPropertyValue(INSTANCE.getUserEntryFilterPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void setUserEntryFilter(String value) {
      impl.setPropertyValue(INSTANCE.getUserEntryFilterPropertyDefinition(), value);
    }



    /**
     * {@inheritDoc}
     */
    public ManagedObjectDefinition<? extends NetworkGroupCriteriaCfgClient, ? extends NetworkGroupCriteriaCfg> definition() {
      return INSTANCE;
    }



    /**
     * {@inheritDoc}
     */
    public PropertyProvider properties() {
      return impl;
    }



    /**
     * {@inheritDoc}
     */
    public void commit() throws ManagedObjectAlreadyExistsException,
        MissingMandatoryPropertiesException, ConcurrentModificationException,
        OperationRejectedException, AuthorizationException,
        CommunicationException {
      impl.commit();
    }

  }



  /**
   * Managed object server implementation.
   */
  private static class NetworkGroupCriteriaCfgServerImpl implements
    NetworkGroupCriteriaCfg {

    // Private implementation.
    private ServerManagedObject<? extends NetworkGroupCriteriaCfg> impl;

    // The value of the "allowed-auth-method" property.
    private final SortedSet<AllowedAuthMethod> pAllowedAuthMethod;

    // The value of the "allowed-ldap-port" property.
    private final SortedSet<AllowedLDAPPort> pAllowedLDAPPort;

    // The value of the "bind-dn-filter" property.
    private final SortedSet<String> pBindDNFilter;

    // The value of the "ip-address-filter" property.
    private final SortedSet<AddressMask> pIPAddressFilter;

    // The value of the "is-security-mandatory" property.
    private final boolean pIsSecurityMandatory;

    // The value of the "user-entry-filter" property.
    private final String pUserEntryFilter;



    // Private constructor.
    private NetworkGroupCriteriaCfgServerImpl(ServerManagedObject<? extends NetworkGroupCriteriaCfg> impl) {
      this.impl = impl;
      this.pAllowedAuthMethod = impl.getPropertyValues(INSTANCE.getAllowedAuthMethodPropertyDefinition());
      this.pAllowedLDAPPort = impl.getPropertyValues(INSTANCE.getAllowedLDAPPortPropertyDefinition());
      this.pBindDNFilter = impl.getPropertyValues(INSTANCE.getBindDNFilterPropertyDefinition());
      this.pIPAddressFilter = impl.getPropertyValues(INSTANCE.getIPAddressFilterPropertyDefinition());
      this.pIsSecurityMandatory = impl.getPropertyValue(INSTANCE.getIsSecurityMandatoryPropertyDefinition());
      this.pUserEntryFilter = impl.getPropertyValue(INSTANCE.getUserEntryFilterPropertyDefinition());
    }



    /**
     * {@inheritDoc}
     */
    public void addChangeListener(
        ConfigurationChangeListener<NetworkGroupCriteriaCfg> listener) {
      impl.registerChangeListener(listener);
    }



    /**
     * {@inheritDoc}
     */
    public void removeChangeListener(
        ConfigurationChangeListener<NetworkGroupCriteriaCfg> listener) {
      impl.deregisterChangeListener(listener);
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<AllowedAuthMethod> getAllowedAuthMethod() {
      return pAllowedAuthMethod;
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<AllowedLDAPPort> getAllowedLDAPPort() {
      return pAllowedLDAPPort;
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<String> getBindDNFilter() {
      return pBindDNFilter;
    }



    /**
     * {@inheritDoc}
     */
    public SortedSet<AddressMask> getIPAddressFilter() {
      return pIPAddressFilter;
    }



    /**
     * {@inheritDoc}
     */
    public boolean isIsSecurityMandatory() {
      return pIsSecurityMandatory;
    }



    /**
     * {@inheritDoc}
     */
    public String getUserEntryFilter() {
      return pUserEntryFilter;
    }



    /**
     * {@inheritDoc}
     */
    public Class<? extends NetworkGroupCriteriaCfg> configurationClass() {
      return NetworkGroupCriteriaCfg.class;
    }



    /**
     * {@inheritDoc}
     */
    public DN dn() {
      return impl.getDN();
    }

  }
}
