/*
 * 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.hadoop.fs.s3a.auth;

import java.io.Closeable;
import java.io.IOException;
import java.util.LinkedList;
import java.util.List;

import com.amazonaws.auth.Signer;
import com.amazonaws.auth.SignerFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.s3a.auth.delegation.DelegationTokenProvider;
import org.apache.hadoop.fs.s3a.impl.V2Migration;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.util.ReflectionUtils;

import static org.apache.hadoop.fs.s3a.Constants.CUSTOM_SIGNERS;

/**
 * Class to handle custom signers.
 */
public class SignerManager implements Closeable {

  private static final Logger LOG = LoggerFactory
      .getLogger(SignerManager.class);

  private final List<AwsSignerInitializer> initializers = new LinkedList<>();

  private final String bucketName;
  private final DelegationTokenProvider delegationTokenProvider;
  private final Configuration ownerConf;
  private final UserGroupInformation ownerUgi;

  public SignerManager(String bucketName,
      DelegationTokenProvider delegationTokenProvider, Configuration ownerConf,
      UserGroupInformation ownerUgi) {
    this.bucketName = bucketName;
    this.delegationTokenProvider = delegationTokenProvider;
    this.ownerConf = ownerConf;
    this.ownerUgi = ownerUgi;
  }

  /**
   * Initialize custom signers and register them with the AWS SDK.
   *
   */
  public void initCustomSigners() {
    String[] customSigners = ownerConf.getTrimmedStrings(CUSTOM_SIGNERS);
    if (customSigners == null || customSigners.length == 0) {
      // No custom signers specified, nothing to do.
      LOG.debug("No custom signers specified");
      return;
    }

    V2Migration.v1CustomSignerUsed();

    for (String customSigner : customSigners) {
      String[] parts = customSigner.split(":");
      if (!(parts.length == 1 || parts.length == 2 || parts.length == 3)) {
        String message = "Invalid format (Expected name, name:SignerClass,"
            + " name:SignerClass:SignerInitializerClass)"
            + " for CustomSigner: [" + customSigner + "]";
        LOG.error(message);
        throw new IllegalArgumentException(message);
      }
      if (parts.length == 1) {
        // Nothing to do. Trying to use a pre-defined Signer
      } else {
        // Register any custom Signer
        maybeRegisterSigner(parts[0], parts[1], ownerConf);

        // If an initializer is specified, take care of instantiating it and
        // setting it up
        if (parts.length == 3) {
          Class<? extends AwsSignerInitializer> clazz = null;
          try {
            clazz = (Class<? extends AwsSignerInitializer>) ownerConf
                .getClassByName(parts[2]);
          } catch (ClassNotFoundException e) {
            throw new RuntimeException(String.format(
                "SignerInitializer class" + " [%s] not found for signer [%s]",
                parts[2], parts[0]), e);
          }
          LOG.debug("Creating signer initializer: [{}] for signer: [{}]",
              parts[2], parts[0]);
          AwsSignerInitializer signerInitializer = ReflectionUtils
              .newInstance(clazz, null);
          initializers.add(signerInitializer);
          signerInitializer
              .registerStore(bucketName, ownerConf, delegationTokenProvider,
                  ownerUgi);
        }
      }
    }
  }

  /*
   * Make sure the signer class is registered once with the AWS SDK
   */
  private static void maybeRegisterSigner(String signerName,
      String signerClassName, Configuration conf) {
    try {
      SignerFactory.getSignerByTypeAndService(signerName, null);
    } catch (IllegalArgumentException e) {
      // Signer is not registered with the AWS SDK.
      // Load the class and register the signer.
      Class<? extends Signer> clazz = null;
      try {
        clazz = (Class<? extends Signer>) conf.getClassByName(signerClassName);
      } catch (ClassNotFoundException cnfe) {
        throw new RuntimeException(String
            .format("Signer class [%s] not found for signer [%s]",
                signerClassName, signerName), cnfe);
      }
      LOG.debug("Registering Custom Signer - [{}->{}]", signerName,
          clazz.getName());
      synchronized (SignerManager.class) {
        SignerFactory.registerSigner(signerName, clazz);
      }
    }
  }

  @Override public void close() throws IOException {
    LOG.debug("Unregistering fs from {} initializers", initializers.size());
    for (AwsSignerInitializer initializer : initializers) {
      initializer
          .unregisterStore(bucketName, ownerConf, delegationTokenProvider,
              ownerUgi);
    }
  }
}