/*
 * 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.slider.server.appmaster.security;

import com.google.common.base.Preconditions;

import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.security.UserGroupInformation;
import static org.apache.slider.core.main.LauncherExitCodes.EXIT_UNAUTHORIZED;
import org.apache.slider.common.SliderKeys;
import org.apache.slider.common.SliderXmlConfKeys;
import org.apache.slider.common.tools.SliderUtils;
import org.apache.slider.core.conf.AggregateConf;
import org.apache.slider.core.exceptions.SliderException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;

/**
 * Class keeping code security information
 */
public class SecurityConfiguration {

  protected static final Logger log =
      LoggerFactory.getLogger(SecurityConfiguration.class);
  private final Configuration configuration;
  private final AggregateConf instanceDefinition;
  private String clusterName;

  public SecurityConfiguration(Configuration configuration,
                               AggregateConf instanceDefinition,
                               String clusterName) throws SliderException {
    Preconditions.checkNotNull(configuration);
    Preconditions.checkNotNull(instanceDefinition);
    Preconditions.checkNotNull(clusterName);
    this.configuration = configuration;
    this.instanceDefinition = instanceDefinition;
    this.clusterName = clusterName;
    validate();
  }

  private void validate() throws SliderException {
    if (isSecurityEnabled()) {
      String principal = instanceDefinition.getAppConfOperations()
          .getComponent(SliderKeys.COMPONENT_AM).get(SliderXmlConfKeys.KEY_KEYTAB_PRINCIPAL);
      if(SliderUtils.isUnset(principal)) {
        // if no login identity is available, fail
        UserGroupInformation loginUser = null;
        try {
          loginUser = getLoginUser();
        } catch (IOException e) {
          throw new SliderException(EXIT_UNAUTHORIZED, e,
                                    "No principal configured for the application and "
                                    + "exception raised during retrieval of login user. "
                                    + "Unable to proceed with application "
                                    + "initialization.  Please ensure a value "
                                    + "for %s exists in the application "
                                    + "configuration or the login issue is addressed",
                                    SliderXmlConfKeys.KEY_KEYTAB_PRINCIPAL);
        }
        if (loginUser == null) {
          throw new SliderException(EXIT_UNAUTHORIZED,
                                    "No principal configured for the application "
                                    + "and no login user found. "
                                    + "Unable to proceed with application "
                                    + "initialization.  Please ensure a value "
                                    + "for %s exists in the application "
                                    + "configuration or the login issue is addressed",
                                    SliderXmlConfKeys.KEY_KEYTAB_PRINCIPAL);
        }
      }
      // ensure that either local or distributed keytab mechanism is enabled,
      // but not both
      String keytabFullPath = instanceDefinition.getAppConfOperations()
          .getComponent(SliderKeys.COMPONENT_AM)
          .get(SliderXmlConfKeys.KEY_AM_KEYTAB_LOCAL_PATH);
      String keytabName = instanceDefinition.getAppConfOperations()
          .getComponent(SliderKeys.COMPONENT_AM)
          .get(SliderXmlConfKeys.KEY_AM_LOGIN_KEYTAB_NAME);
      if (SliderUtils.isSet(keytabFullPath) && SliderUtils.isSet(keytabName)) {
        throw new SliderException(EXIT_UNAUTHORIZED,
                                  "Both a keytab on the cluster host (%s) and a"
                                  + " keytab to be retrieved from HDFS (%s) are"
                                  + " specified.  Please configure only one keytab"
                                  + " retrieval mechanism.",
                                  SliderXmlConfKeys.KEY_AM_KEYTAB_LOCAL_PATH,
                                  SliderXmlConfKeys.KEY_AM_LOGIN_KEYTAB_NAME);

      }
    }
  }

  protected UserGroupInformation getLoginUser() throws IOException {
    return UserGroupInformation.getLoginUser();
  }

  public boolean isSecurityEnabled () {
    return SliderUtils.isHadoopClusterSecure(configuration);
  }

  public String getPrincipal () throws IOException {
    String principal = instanceDefinition.getAppConfOperations()
        .getComponent(SliderKeys.COMPONENT_AM).get(SliderXmlConfKeys.KEY_KEYTAB_PRINCIPAL);
    if (SliderUtils.isUnset(principal)) {
      principal = UserGroupInformation.getLoginUser().getShortUserName();
      log.info("No principal set in the slider configuration.  Will use AM login"
               + " identity {} to attempt keytab-based login", principal);
    }

    return principal;
  }

  public boolean isKeytabProvided() {
    String keytabLocalPath = instanceDefinition.getAppConfOperations()
        .getComponent(SliderKeys.COMPONENT_AM)
        .get(SliderXmlConfKeys.KEY_AM_KEYTAB_LOCAL_PATH);
    String keytabName = instanceDefinition.getAppConfOperations()
        .getComponent(SliderKeys.COMPONENT_AM)
        .get(SliderXmlConfKeys.KEY_AM_LOGIN_KEYTAB_NAME);
    return StringUtils.isNotBlank(keytabLocalPath)
        || StringUtils.isNotBlank(keytabName);
  }

  public File getKeytabFile(AggregateConf instanceDefinition)
      throws SliderException, IOException {
    String keytabFullPath = instanceDefinition.getAppConfOperations()
        .getComponent(SliderKeys.COMPONENT_AM)
        .get(SliderXmlConfKeys.KEY_AM_KEYTAB_LOCAL_PATH);
    File localKeytabFile;
    if (SliderUtils.isUnset(keytabFullPath)) {
      // get the keytab
      String keytabName = instanceDefinition.getAppConfOperations()
          .getComponent(SliderKeys.COMPONENT_AM).
              get(SliderXmlConfKeys.KEY_AM_LOGIN_KEYTAB_NAME);
      log.info("No host keytab file path specified. Will attempt to retrieve"
               + " keytab file {} as a local resource for the container",
               keytabName);
      // download keytab to local, protected directory
      localKeytabFile = new File(SliderKeys.KEYTAB_DIR, keytabName);
    } else {
      log.info("Using host keytab file {} for login", keytabFullPath);
      localKeytabFile = new File(keytabFullPath);
    }
    return localKeytabFile;
  }

}
