/*
 * 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.geode.security.generator;

import java.security.Principal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.apache.logging.log4j.Logger;

import org.apache.geode.internal.logging.LogService;
import org.apache.geode.security.AuthInitialize;
import org.apache.geode.security.Authenticator;
import org.apache.geode.security.templates.DummyAuthenticator;
import org.apache.geode.security.templates.LdapUserAuthenticator;
import org.apache.geode.security.templates.PKCSAuthenticator;

/**
 * Encapsulates obtaining valid and invalid credentials. Implementations will be for different kinds
 * of authentication schemes.
 *
 * @since GemFire 5.5
 */
public abstract class CredentialGenerator {

  private static final Logger logger = LogService.getLogger();

  /**
   * A set of properties that should be added to the Gemfire system properties before using the
   * authentication module.
   */
  private Properties systemProperties = null;

  /**
   * A set of properties that should be added to the java system properties before using the
   * authentication module.
   */
  protected Properties javaProperties = null;

  /**
   * A factory method to create a new instance of an {@link CredentialGenerator} for the given
   * {@link ClassCode}. Caller is supposed to invoke {@link CredentialGenerator#init} immediately
   * after obtaining the instance.
   *
   * @param classCode the {@code ClassCode} of the {@code CredentialGenerator} implementation
   *
   * @return an instance of {@code CredentialGenerator} for the given class code
   */
  public static CredentialGenerator create(final ClassCode classCode) {
    switch (classCode.classType) {
      // Removing dummy one to reduce test run times
      // case ClassCode.ID_DUMMY:
      // return new DummyCredentialGenerator();
      case ClassCode.ID_LDAP:
        return new LdapUserCredentialGenerator();
      // case ClassCode.ID_SSL:ø
      // return new SSLCredentialGenerator();
      case ClassCode.ID_PKCS:
        return new PKCSCredentialGenerator();
      default:
        return null;
    }
  }

  /**
   * Initialize the credential generator.
   *
   * @throws IllegalArgumentException when there is a problem during initialization
   */
  public void init() throws IllegalArgumentException {
    this.systemProperties = initialize();
    logger.info("Generating CredentialGenerator with {}", this.systemProperties);
  }

  /**
   * @return A set of extra properties that should be added to Gemfire system properties when not
   *         null.
   */
  public Properties getSystemProperties() {
    return this.systemProperties;
  }

  /**
   * @return A set of extra properties that should be added to Gemfire system properties when not
   *         null.
   */
  public Properties getJavaProperties() {
    return this.javaProperties;
  }

  /**
   * The {@link ClassCode} of this particular implementation.
   *
   * @return the {@code ClassCode}
   */
  public abstract ClassCode classCode();

  /**
   * The name of the {@link AuthInitialize} factory function that should be used in conjunction with
   * the credentials generated by this generator.
   *
   * @return name of the {@code AuthInitialize} factory function
   */
  public abstract String getAuthInit();

  /**
   * The name of the {@link Authenticator} factory function that should be used in conjunction with
   * the credentials generated by this generator.
   *
   * @return name of the {@code Authenticator} factory function
   */
  public abstract String getAuthenticator();

  /**
   * Get a set of valid credentials generated using the given index.
   */
  public abstract Properties getValidCredentials(final int index);

  /**
   * Get a set of valid credentials for the given {@link Principal}.
   *
   * @return credentials for the given {@code Principal} or null if none possible.
   */
  public abstract Properties getValidCredentials(final Principal principal);

  /**
   * Get a set of invalid credentials generated using the given index.
   */
  public abstract Properties getInvalidCredentials(final int index);

  /**
   * Initialize the credential generator. This is provided separately from the {@link #init()}
   * method for convenience of implementations so that they do not need to store in
   * {@link #systemProperties}. The latter is convenient for the users who do not need to store
   * these properties rather can obtain it later by invoking {@link #getSystemProperties()}
   *
   * <p>
   * Required to be implemented by concrete classes that implement this abstract class.
   *
   * @return A set of extra properties that should be added to Gemfire system properties when not
   *         null.
   *
   * @throws IllegalArgumentException when there is a problem during initialization
   */
  protected abstract Properties initialize() throws IllegalArgumentException;

  /**
   * Enumeration for various {@link CredentialGenerator} implementations.
   *
   * <p>
   * The following schemes are supported as of now: {@code DummyAuthenticator},
   * {@code LdapUserAuthenticator}, {@code PKCSAuthenticator}. In addition SSL socket mode with
   * mutual authentication is also supported.
   *
   * <p>
   * To add a new authentication scheme the following needs to be done:
   * <ul>
   * <li>Add implementations for {@link AuthInitialize} and {@link Authenticator} classes for
   * clients/peers.</li>
   * <li>Add a new enumeration value for the scheme in this class. Notice the size of {@code VALUES}
   * array and increase that if it is getting overflowed. Note the methods and fields for existing
   * schemes and add for the new one in a similar manner.</li>
   * <li>Add an implementation for {@link CredentialGenerator}.</li>
   * <li>Modify the CredentialGenerator.Factory#create [no such Factory exists] method to add
   * creation of an instance of the new implementation for the {@code ClassCode} enumeration
   * value.</li>
   * </ul>
   *
   * <p>
   * All security dunit tests will automagically start testing the new implementation after this.
   *
   * @since GemFire 5.5
   */
  public static class ClassCode {

    private static byte nextOrdinal = 0;

    private static final byte ID_DUMMY = 1;
    private static final byte ID_LDAP = 2;
    private static final byte ID_PKCS = 3;
    private static final byte ID_SSL = 4;

    private static final ClassCode[] VALUES = new ClassCode[10];
    private static final Map CODE_NAME_MAP = new HashMap();

    public static final ClassCode DUMMY =
        new ClassCode(DummyAuthenticator.class.getName() + ".create", ID_DUMMY);
    public static final ClassCode LDAP =
        new ClassCode(LdapUserAuthenticator.class.getName() + ".create", ID_LDAP);
    public static final ClassCode PKCS =
        new ClassCode(PKCSAuthenticator.class.getName() + ".create", ID_PKCS);
    public static final ClassCode SSL = new ClassCode("SSL", ID_SSL);

    /** The name of this class. */
    private final String name;

    /** byte used as ordinal to represent this class */
    private final byte ordinal;

    /**
     * One of the following: ID_DUMMY, ID_LDAP, ID_PKCS
     */
    private final byte classType;

    /** Creates a new instance of class code. */
    private ClassCode(final String name, final byte classType) {
      this.name = name;
      this.classType = classType;
      this.ordinal = nextOrdinal++;
      VALUES[this.ordinal] = this;
      CODE_NAME_MAP.put(name, this);
    }

    public boolean isDummy() {
      return this.classType == ID_DUMMY;
    }

    public boolean isLDAP() {
      return this.classType == ID_LDAP;
    }

    public boolean isPKCS() {
      return this.classType == ID_PKCS;
    }

    public boolean isSSL() {
      return this.classType == ID_SSL;
    }

    /**
     * Returns the {@code ClassCode} represented by specified ordinal.
     */
    public static ClassCode fromOrdinal(final byte ordinal) {
      return VALUES[ordinal];
    }

    /**
     * Returns the {@code ClassCode} represented by specified string.
     */
    public static ClassCode parse(final String operationName) {
      return (ClassCode) CODE_NAME_MAP.get(operationName);
    }

    /**
     * Returns all the possible values.
     */
    public static List getAll() {
      final List codes = new ArrayList();
      for (Iterator iter = CODE_NAME_MAP.values().iterator(); iter.hasNext();) {
        codes.add(iter.next());
      }
      return codes;
    }

    /**
     * Returns the ordinal for this operation code.
     *
     * @return the ordinal of this operation.
     */
    public byte toOrdinal() {
      return this.ordinal;
    }

    /**
     * Returns a string representation for this operation.
     *
     * @return the name of this operation.
     */
    @Override
    public String toString() {
      return this.name;
    }

    /**
     * Indicates whether other object is same as this one.
     *
     * @return true if other object is same as this one.
     */
    @Override
    public boolean equals(final Object obj) {
      if (obj == this) {
        return true;
      }
      if (!(obj instanceof ClassCode)) {
        return false;
      }
      final ClassCode other = (ClassCode) obj;
      return other.ordinal == this.ordinal;
    }

    /**
     * Indicates whether other {@code ClassCode} is same as this one.
     *
     * @return true if other {@code ClassCode} is same as this one.
     */
    public boolean equals(final ClassCode opCode) {
      return opCode != null && opCode.ordinal == this.ordinal;
    }

    /**
     * Returns a hash code value for this {@code ClassCode} which is the same as its ordinal.
     *
     * @return the ordinal of this operation.
     */
    @Override
    public int hashCode() {
      return this.ordinal;
    }
  }
}
