/*
 * 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.logging.internal.log4j.api.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;
    }
  }
}
