/**
 * 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.ambari.server.state.kerberos;

import java.util.TreeMap;
import java.util.Map;

/**
 * KerberosPrincipalDescriptor is an implementation of an AbstractKerberosDescriptor that
 * encapsulates data related to a Kerberos principal.  This class is typically associated with the
 * KerberosKeytabDescriptor via a KerberosIdentityDescriptor.
 * <p/>
 * A KerberosPrincipalDescriptor has the following properties:
 * <ul>
 * <li>value</li>
 * <li>type</li>
 * <li>configuration</li>
 * <li>local_username</li>
 * </ul>
 * <p/>
 * The following JSON Schema will yield a valid KerberosPrincipalDescriptor
 * <pre>
 *   {
 *      "$schema": "http://json-schema.org/draft-04/schema#",
 *      "title": "KerberosIdentityDescriptor",
 *      "description": "Describes a Kerberos principal and associated details",
 *      "type": "object",
 *      "properties": {
 *        "value": {
 *          "description": "The pattern to use to generate the principal",
 *          "type": "string"
 *        },
 *        "type": {
 *          "description": "The type of principal - either 'service' or 'user'",
 *          "type": "string"
 *        },
 *        "configuration": {
 *          "description": "The configuration type and property name indicating the property to be
 *                          updated with the generated principal - format: config-type/property.name",
 *          "type": "string"
 *        },
 *        "local_username": {
 *          "description": "The local username this principal maps to - optional if no mapping is needed",
 *          "type": "string"
 *        }
 *      }
 *   }
 * </pre>
 * <p/>
 * In this implementation,
 * {@link org.apache.ambari.server.state.kerberos.AbstractKerberosDescriptor#name} will hold the
 * KerberosPrincipalDescriptor#value value
 */
public class KerberosPrincipalDescriptor extends AbstractKerberosDescriptor {

  /**
   * A string declaring the type of principal this KerberosPrincipalDescriptor represents.
   * <p/>
   * Expecting either "service" or "user"
   */
  private KerberosPrincipalType type = null;

  /**
   * A string declaring configuration type and property name indicating the property to be updated
   * with the generated principal
   * <p/>
   * This String is expected to be in the following format: configuration-type/property.name, where
   * <ul>
   * <li>configuration-type is the configuration file type where the property exists</li>
   * <li>property.value is the name of the relevant property within the configuration</li>
   * </ul>
   * <p/>
   * Example: hdfs-site/dfs.namenode.kerberos.principal
   */
  private String configuration = null;

  /**
   * a String indicating the local username related to this principal, or null of no local mapping is
   * needed or available.
   * <p/>
   * This value may be using in generating auth_to_local configuration settings.
   */
  private String localUsername = null;

  /**
   * Creates a new KerberosPrincipalDescriptor
   *
   * @param principal the principal name
   * @param type the principal type (user, service, etc...)
   * @param configuration the configuration used to store the principal name
   * @param localUsername the local username to map to the principal
   */
  public KerberosPrincipalDescriptor(String principal, KerberosPrincipalType type, String configuration, String localUsername) {
    // The name for this KerberosPrincipalDescriptor is stored in the "value" entry in the map
    // This is not automatically set by the super classes.
    setName(principal);
    setType(type);
    setConfiguration(configuration);
    setLocalUsername(localUsername);
  }

  /**
   * Creates a new KerberosPrincipalDescriptor
   * <p/>
   * See {@link org.apache.ambari.server.state.kerberos.KerberosPrincipalDescriptor} for the JSON
   * Schema that may be used to generate this map.
   *
   * @param data a Map of values use to populate the data for the new instance
   * @see org.apache.ambari.server.state.kerberos.KerberosPrincipalDescriptor
   */
  public KerberosPrincipalDescriptor(Map<?, ?> data) {
    this(getStringValue(data, "value"),
        getKerberosPrincipalTypeValue(data, "type"),
        getStringValue(data, "configuration"),
        getStringValue(data, "local_username")
    );
  }

  /**
   * Gets the value (or principal name pattern) for this KerberosPrincipalDescriptor
   * <p/>
   * The value may include variable placeholders to be replaced as needed
   * <ul>
   * <li>
   * ${variable} placeholders are replaced on the server - see
   * {@link VariableReplacementHelper#replaceVariables(String, Map)}
   * </li>
   * <li>the _HOST placeholder is replaced on the hosts to dynamically populate the relevant hostname</li>
   * </ul>
   *
   * @return a String declaring this principal's value
   * @see VariableReplacementHelper#replaceVariables(String, Map)
   */
  public String getValue() {
    return getName();
  }

  /**
   * Sets the value (or principal name pattern) for this KerberosPrincipalDescriptor
   *
   * @param value a String declaring this principal's value
   * @see #getValue()
   */
  public void setValue(String value) {
    setName(value);
  }

  /**
   * Gets the type of this KerberosPrincipalDescriptor
   *
   * @return a KerberosPrincipalType declaring the type of this KerberosPrincipalDescriptor
   */
  public KerberosPrincipalType getType() {
    return type;
  }

  /**
   * Sets the type of this KerberosPrincipalDescriptor
   * <p/>
   * The value should be either "service" or "user"
   *
   * @param type a KerberosPrincipalType declaring the type of this KerberosPrincipalDescriptor
   */
  public void setType(KerberosPrincipalType type) {
    this.type = type;
  }

  /**
   * Gets the configuration type and property name indicating the property to be updated with the
   * generated principal
   *
   * @return a String declaring the configuration type and property name indicating the property to
   * be updated with the generated principal
   * #see #configuration
   */
  public String getConfiguration() {
    return configuration;
  }

  /**
   * Sets the configuration type and property name indicating the property to be updated with the
   * generated principal
   *
   * @param configuration a String declaring the configuration type and property name indicating the
   *                      property to be updated with the generated principal
   * @see #configuration
   */
  public void setConfiguration(String configuration) {
    this.configuration = configuration;
  }

  /**
   * Gets the local username associated with this principal
   *
   * @return a String indicating the local username related to this principal, or null of not local
   * mapping is needed/available
   */
  public String getLocalUsername() {
    return localUsername;
  }

  /**
   * Sets the local username associated with this principal
   *
   * @param localUsername a String indicating the local username related to this principal, or null
   *                      of no local mapping is needed/available
   */
  public void setLocalUsername(String localUsername) {
    this.localUsername = localUsername;
  }

  /**
   * Updates this KerberosPrincipalDescriptor with data from another KerberosPrincipalDescriptor
   * <p/>
   * Properties will be updated if the relevant updated values are not null.
   *
   * @param updates the KerberosPrincipalDescriptor containing the updated values
   */
  public void update(KerberosPrincipalDescriptor updates) {
    if (updates != null) {
      String updatedValue;

      updatedValue = updates.getValue();
      if (updatedValue != null) {
        setValue(updatedValue);
      }

      KerberosPrincipalType updatedType = updates.getType();
      if (updatedType != null) {
        setType(updatedType);
      }

      updatedValue = updates.getConfiguration();
      if (updatedValue != null) {
        setConfiguration(updatedValue);
      }

      updatedValue = updates.getLocalUsername();
      if (updatedValue != null) {
        setLocalUsername(updatedValue);
      }
    }
  }

  /**
   * Creates a Map of values that can be used to create a copy of this KerberosPrincipalDescriptor
   * or generate the JSON structure described in
   * {@link org.apache.ambari.server.state.kerberos.KerberosPrincipalDescriptor}
   *
   * @return a Map of values for this KerberosPrincipalDescriptor
   * @see org.apache.ambari.server.state.kerberos.KerberosPrincipalDescriptor
   */
  @Override
  public Map<String, Object> toMap() {
    Map<String, Object> map = new TreeMap<String, Object>();

    map.put("value", getValue());
    map.put("type", KerberosPrincipalType.translate(getType()));
    map.put("configuration", getConfiguration());
    map.put("local_username", getLocalUsername());

    return map;
  }

  @Override
  public int hashCode() {
    return super.hashCode() +
        ((getConfiguration() == null)
            ? 0
            : getConfiguration().hashCode()) +
        ((getType() == null)
            ? 0
            : getType().hashCode());
  }

  @Override
  public boolean equals(Object object) {
    if (object == null) {
      return false;
    } else if (object == this) {
      return true;
    } else if (object.getClass() == KerberosPrincipalDescriptor.class) {
      KerberosPrincipalDescriptor descriptor = (KerberosPrincipalDescriptor) object;
      return super.equals(object) &&
          (
              (getConfiguration() == null)
                  ? (descriptor.getConfiguration() == null)
                  : getConfiguration().equals(descriptor.getConfiguration())
          ) &&
          (
              (getType() == null)
                  ? (descriptor.getType() == null)
                  : getType().equals(descriptor.getType())
          );
    } else {
      return false;
    }
  }

  /**
   * Translates a string value representing a principal type to a KerberosPrincipalType.
   *
   * @param map a Map containing the relevant data
   * @param key a String declaring the item to retrieve
   * @return a KerberosPrincipalType, or null is not specified in the map
   * @throws IllegalArgumentException if the principal type value is not one of the expected types.
   */
  private static KerberosPrincipalType getKerberosPrincipalTypeValue(Map<?, ?> map, String key) {
    String type = getStringValue(map, key);
    if ((type == null) || type.isEmpty()) {
      return null;
    } else {
      return KerberosPrincipalType.valueOf(type.toUpperCase());
    }
  }
}
