/*
 * 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.accumulo.core.client.impl;

import static java.nio.charset.StandardCharsets.UTF_8;

import java.nio.ByteBuffer;
import java.util.Base64;

import org.apache.accumulo.core.client.AccumuloClient;
import org.apache.accumulo.core.client.AccumuloSecurityException;
import org.apache.accumulo.core.client.impl.thrift.SecurityErrorCode;
import org.apache.accumulo.core.client.security.tokens.AuthenticationToken;
import org.apache.accumulo.core.client.security.tokens.AuthenticationToken.AuthenticationTokenSerializer;
import org.apache.accumulo.core.security.thrift.TCredentials;

/**
 * A wrapper for internal use. This class carries the instance, principal, and authentication token
 * for use in the public API, in a non-serialized form. This is important, so that the
 * authentication token carried in a {@link AccumuloClient} can be destroyed, invalidating future
 * RPC operations from that {@link AccumuloClient}.
 * <p>
 * See ACCUMULO-1312
 *
 * @since 1.6.0
 */
public class Credentials {

  private String principal;
  private AuthenticationToken token;

  /**
   * Creates a new credentials object.
   *
   * @param principal
   *          unique identifier for the entity (e.g. a user or service) authorized for these
   *          credentials
   * @param token
   *          authentication token used to prove that the principal for these credentials has been
   *          properly verified
   */
  public Credentials(String principal, AuthenticationToken token) {
    this.principal = principal;
    this.token = token;
  }

  /**
   * Gets the principal.
   *
   * @return unique identifier for the entity (e.g. a user or service) authorized for these
   *         credentials
   */
  public String getPrincipal() {
    return principal;
  }

  /**
   * Gets the authentication token.
   *
   * @return authentication token used to prove that the principal for these credentials has been
   *         properly verified
   */
  public AuthenticationToken getToken() {
    return token;
  }

  /**
   * Converts the current object to the relevant thrift type. The object returned from this contains
   * a non-destroyable version of the {@link AuthenticationToken}, so this should be used just
   * before placing on the wire, and references to it should be tightly controlled.
   *
   * @param instanceID
   *          Accumulo instance ID
   * @return Thrift credentials
   * @throws RuntimeException
   *           if the authentication token has been destroyed (expired)
   */
  public TCredentials toThrift(String instanceID) {
    TCredentials tCreds = new TCredentials(getPrincipal(), getToken().getClass().getName(),
        ByteBuffer.wrap(AuthenticationTokenSerializer.serialize(getToken())), instanceID);
    if (getToken().isDestroyed())
      throw new RuntimeException("Token has been destroyed",
          new AccumuloSecurityException(getPrincipal(), SecurityErrorCode.TOKEN_EXPIRED));
    return tCreds;
  }

  /**
   * Converts a given thrift object to our internal Credentials representation.
   *
   * @param serialized
   *          a Thrift encoded set of credentials
   * @return a new Credentials instance; destroy the token when you're done.
   */
  public static Credentials fromThrift(TCredentials serialized) {
    return new Credentials(serialized.getPrincipal(), AuthenticationTokenSerializer
        .deserialize(serialized.getTokenClassName(), serialized.getToken()));
  }

  /**
   * Converts the current object to a serialized form. The object returned from this contains a
   * non-destroyable version of the {@link AuthenticationToken}, so references to it should be
   * tightly controlled.
   *
   * @return serialized form of these credentials
   */
  public final String serialize() {
    return (getPrincipal() == null ? "-"
        : Base64.getEncoder().encodeToString(getPrincipal().getBytes(UTF_8)))
        + ":"
        + (getToken() == null ? "-"
            : Base64.getEncoder().encodeToString(getToken().getClass().getName().getBytes(UTF_8)))
        + ":"
        + (getToken() == null ? "-"
            : Base64.getEncoder()
                .encodeToString(AuthenticationTokenSerializer.serialize(getToken())));
  }

  /**
   * Converts the serialized form to an instance of {@link Credentials}. The original serialized
   * form will not be affected.
   *
   * @param serializedForm
   *          serialized form of credentials
   * @return deserialized credentials
   */
  public static final Credentials deserialize(String serializedForm) {
    String[] split = serializedForm.split(":", 3);
    String principal = split[0].equals("-") ? null
        : new String(Base64.getDecoder().decode(split[0]), UTF_8);
    String tokenType = split[1].equals("-") ? null
        : new String(Base64.getDecoder().decode(split[1]), UTF_8);
    AuthenticationToken token = null;
    if (!split[2].equals("-")) {
      byte[] tokenBytes = Base64.getDecoder().decode(split[2]);
      token = AuthenticationTokenSerializer.deserialize(tokenType, tokenBytes);
    }
    return new Credentials(principal, token);
  }

  @Override
  public int hashCode() {
    return getPrincipal() == null ? 0 : getPrincipal().hashCode();
  }

  @Override
  public boolean equals(Object obj) {
    if (obj == null || !(obj instanceof Credentials))
      return false;
    Credentials other = Credentials.class.cast(obj);
    boolean pEq = getPrincipal() == null ? (other.getPrincipal() == null)
        : (getPrincipal().equals(other.getPrincipal()));
    if (!pEq)
      return false;
    return getToken() == null ? (other.getToken() == null) : (getToken().equals(other.getToken()));
  }

  @Override
  public String toString() {
    return getClass().getName() + ":" + getPrincipal() + ":"
        + (getToken() == null ? null : getToken().getClass().getName()) + ":<hidden>";
  }
}
