/**
 * 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
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * 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.ozone.om;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;

import com.google.common.base.Optional;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.hdds.annotation.InterfaceAudience;
import org.apache.hadoop.hdds.annotation.InterfaceStability;
import org.apache.hadoop.hdds.conf.OzoneConfiguration;
import org.apache.hadoop.ozone.om.exceptions.OMException;
import org.apache.hadoop.ozone.OzoneConsts;
import org.apache.hadoop.ozone.om.helpers.TenantUserList;
import org.apache.hadoop.ozone.om.multitenant.AuthorizerLock;
import org.apache.hadoop.ozone.om.multitenant.MultiTenantAccessController.Acl;
import org.apache.hadoop.ozone.om.multitenant.MultiTenantAccessController.Policy;
import org.apache.hadoop.ozone.om.multitenant.OMRangerBGSyncService;
import org.apache.hadoop.ozone.om.multitenant.OzoneOwnerPrincipal;
import org.apache.hadoop.ozone.om.multitenant.Tenant;
import org.apache.hadoop.security.SecurityUtil;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
import org.slf4j.Logger;

import static org.apache.hadoop.ozone.OzoneConsts.OZONE_TENANT_RANGER_POLICY_LABEL;
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_KERBEROS_KEYTAB_FILE_KEY;
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_KERBEROS_PRINCIPAL_KEY;
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_MULTITENANCY_ENABLED;
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_MULTITENANCY_ENABLED_DEFAULT;
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_RANGER_HTTPS_ADMIN_API_PASSWD;
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_OM_RANGER_HTTPS_ADMIN_API_USER;
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_RANGER_HTTPS_ADDRESS_KEY;
import static org.apache.hadoop.ozone.om.OMConfigKeys.OZONE_RANGER_SERVICE;
import static org.apache.hadoop.ozone.om.OMMultiTenantManagerImpl.OZONE_OM_TENANT_DEV_SKIP_RANGER;
import static org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.ALL;
import static org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.CREATE;
import static org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.LIST;
import static org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.READ;
import static org.apache.hadoop.ozone.security.acl.IAccessAuthorizer.ACLType.READ_ACL;

/**
 * OM MultiTenant manager interface.
 */
@InterfaceAudience.Private
@InterfaceStability.Unstable
public interface OMMultiTenantManager {
  /* TODO: Outdated
   * Init multi-tenant manager. Performs initialization e.g.
   *  - Initialize Multi-Tenant-Gatekeeper-Plugin
   *  - Validate Multi-Tenant Bucket-NameSpaces
   *  - Validate Multi-Tenant Account-NameSpaces
   *  - Validating various OM (Multi-Tenant state)tables and corresponding
   *    state in IMultiTenantGateKeeperPlugin (Ranger/Native/AnyOtherPlugIn).
   *  - Setup SuperUsers for Multi-Tenant environment from Ozone-Conf
   *  - Periodic BackGround thread to keep MultiTenant-State consistent e.g.
   *       . superusers  <-in-sync-> OzoneConf,
   *       . OM-DB state <-in-sync-> IMultiTenantGateKeeperPluginState
   *       . OM DB state is always the source of truth.
   */

  /**
   * Start background thread(s) in the multi-tenant manager.
   */
  void start() throws IOException;

  /**
   * Stop background thread(s) in the multi-tenant manager.
   */
  void stop() throws IOException;

  /**
   * Returns the instance of OMRangerBGSyncService.
   */
  OMRangerBGSyncService getOMRangerBGSyncService();

  /**
   * Returns the corresponding OzoneManager instance.
   *
   * @return OMMetadataManager
   */
  OMMetadataManager getOmMetadataManager();

  TenantOp getAuthorizerOp();

  TenantOp getCacheOp();

  /**
   * Given an accessId, return kerberos user name for the tenant user.
   */
  String getUserNameGivenAccessId(String accessId);

  /**
   * Get the default Access ID string given tenant name and user name.
   * @param tenantId tenant name
   * @param userPrincipal user name
   * @return access ID in the form of tenantName$username
   */
  static String getDefaultAccessId(String tenantId, String userPrincipal) {
    return tenantId + OzoneConsts.TENANT_ID_USERNAME_DELIMITER + userPrincipal;
  }

  /**
   * Returns true if user is the tenant's admin or Ozone admin, false otherwise.
   * @param callerUgi caller's UserGroupInformation
   * @param tenantId tenant name
   * @param delegated if set to true, checks if the user is a delegated tenant
   *                  admin; if set to false, checks if the user is a tenant
   *                  admin, delegated or not
   */
  boolean isTenantAdmin(UserGroupInformation callerUgi, String tenantId,
      boolean delegated);

  /**
   * List all the user & accessIDs of all users that belong to this Tenant.
   * Note this read is unprotected. See OzoneManager#listUserInTenant
   * @param tenantID
   * @return List of users
   */
  TenantUserList listUsersInTenant(String tenantID, String prefix)
      throws IOException;
  /**
   * Given an access ID return its corresponding tenant.
   * @param accessID
   * @return String tenant name
   */
  Optional<String> getTenantForAccessID(String accessID) throws IOException;

  /**
   * Get default user role name given tenant name.
   * @param tenantId tenant name
   * @return user role name. e.g. tenant1-UserRole
   */
  static String getDefaultUserRoleName(String tenantId) {
    return tenantId + OzoneConsts.DEFAULT_TENANT_ROLE_USER_SUFFIX;
  }

  /**
   * Get default admin role name given tenant name.
   * @param tenantId tenant name
   * @return admin role name. e.g. tenant1-AdminRole
   */
  static String getDefaultAdminRoleName(String tenantId) {
    return tenantId + OzoneConsts.DEFAULT_TENANT_ROLE_ADMIN_SUFFIX;
  }

  /**
   * Get default bucket namespace (volume) policy name given tenant name.
   * @param tenantId tenant name
   * @return bucket namespace (volume) policy name. e.g. tenant1-VolumeAccess
   */
  static String getDefaultBucketNamespacePolicyName(String tenantId) {
    return tenantId + OzoneConsts.DEFAULT_TENANT_BUCKET_NAMESPACE_POLICY_SUFFIX;
  }

  /**
   * Get default bucket policy name given tenant name.
   * @param tenantId tenant name
   * @return bucket policy name. e.g. tenant1-BucketAccess
   */
  static String getDefaultBucketPolicyName(String tenantId) {
    return tenantId + OzoneConsts.DEFAULT_TENANT_BUCKET_POLICY_SUFFIX;
  }

  /**
   * Passes check only when caller is an Ozone (cluster) admin, throws
   * OMException otherwise.
   * @throws OMException PERMISSION_DENIED
   */
  void checkAdmin() throws OMException;

  /**
   * Check if caller is a tenant admin of the specified tenant.
   * Ozone admins will always pass this check.
   * Throws PERMISSION_DENIED if the check failed.
   * @param tenantId tenant name
   * @param delegated if set to true, only delegated tenant admins can pass this
   *                  check; if false, both delegated and non-delegated tenant
   *                  admins will pass this check.
   * @throws OMException PERMISSION_DENIED
   */
  void checkTenantAdmin(String tenantId, boolean delegated) throws OMException;

  /**
   * Check if the tenantId exists in the table, throws TENANT_NOT_FOUND if not.
   */
  void checkTenantExistence(String tenantId) throws OMException;

  /**
   * Retrieve volume name of the tenant.
   *
   * Throws OMException TENANT_NOT_FOUND if tenantId doesn't exist.
   */
  String getTenantVolumeName(String tenantId) throws IOException;

  /**
   * Retrieve user role name of the given tenant.
   * @param tenantId tenant name
   * @return tenant user role name
   */
  String getTenantUserRoleName(String tenantId) throws IOException;

  /**
   * Retrieve admin role name of the given tenant.
   * @param tenantId tenant name
   * @return tenant user role name
   */
  String getTenantAdminRoleName(String tenantId) throws IOException;

  /**
   * Get Tenant object of given tenant name from OM DB.
   * @param tenantId tenant name
   * @return Tenant
   * @throws IOException
   */
  Tenant getTenantFromDBById(String tenantId) throws IOException;

  boolean isUserAccessIdPrincipalOrTenantAdmin(String accessId,
      UserGroupInformation ugi) throws IOException;

  /**
   * Returns true if the tenant doesn't have any accessIds assigned to it
   * Returns false otherwise.
   *
   * @param tenantId
   * @throws IOException
   */
  boolean isTenantEmpty(String tenantId) throws IOException;

  /**
   * Returns true if Multi-Tenancy can be successfully enabled given the OM
   * instance and conf; returns false if ozone.om.multitenancy.enabled = false
   *
   * Config validation will be performed on conf if the intent to enable
   * Multi-Tenancy is specified (i.e. ozone.om.multitenancy.enabled = true),
   * if the validation failed, an exception will be thrown to prevent OM from
   * starting up.
   */
  static boolean checkAndEnableMultiTenancy(
      OzoneManager ozoneManager, OzoneConfiguration conf) {

    // Borrow the logger from OM instance
    final Logger logger = OzoneManager.LOG;

    boolean isS3MultiTenancyEnabled = conf.getBoolean(
        OZONE_OM_MULTITENANCY_ENABLED, OZONE_OM_MULTITENANCY_ENABLED_DEFAULT);

    final boolean devSkipMTCheck = conf.getBoolean(
        OZONE_OM_TENANT_DEV_SKIP_RANGER, false);

    // If ozone.om.multitenancy.enabled = false, skip the validation
    // Or if dev skip check flag is set, skip the validation (used in UT)
    if (!isS3MultiTenancyEnabled || devSkipMTCheck) {
      return isS3MultiTenancyEnabled;
    }

    // Validate configs required to enable S3 multi-tenancy
    if (!ozoneManager.isSecurityEnabled()) {
      isS3MultiTenancyEnabled = false;
      logger.error("Ozone security is required to enable S3 Multi-Tenancy");
    } else if (!SecurityUtil.getAuthenticationMethod(conf).equals(
        AuthenticationMethod.KERBEROS)) {
      isS3MultiTenancyEnabled = false;
      logger.error("Kerberos authentication is required to enable S3 "
          + "Multi-Tenancy");
    }

    // TODO: Validate accessAuthorizer later. We can't do that for now:
    //  1. Tenant acceptance test env (ozonesecure) uses OzoneNativeAuthorizer
    //  2. RangerOzoneAuthorizer is external class

    final String rangerAddress = conf.get(OZONE_RANGER_HTTPS_ADDRESS_KEY);
    if (StringUtils.isBlank(rangerAddress)) {
      isS3MultiTenancyEnabled = false;
      logger.error("{} is required to enable S3 Multi-Tenancy but not set",
          OZONE_RANGER_HTTPS_ADDRESS_KEY);
    }

    final String rangerService = conf.get(OZONE_RANGER_SERVICE);
    if (StringUtils.isBlank(rangerService)) {
      isS3MultiTenancyEnabled = false;
      logger.error("{} is required to enable S3 Multi-Tenancy but not set",
          OZONE_RANGER_SERVICE);
    }

    String fallbackUsername = conf.get(OZONE_OM_RANGER_HTTPS_ADMIN_API_USER);
    String fallbackPassword = conf.get(OZONE_OM_RANGER_HTTPS_ADMIN_API_PASSWD);

    if (fallbackUsername != null && fallbackPassword != null) {
      logger.warn("Detected clear text username and password override configs. "
          + "These will be used to authenticate to Ranger Admin Server instead "
          + "of using the recommended Kerberos principal and keytab "
          + "authentication method. "
          + "This is NOT recommended on a production cluster.");
    } else {
      // Check Kerberos principal and keytab file path configs if not both
      // clear text username and password overrides are set.
      final String omKerbPrinc = conf.get(OZONE_OM_KERBEROS_PRINCIPAL_KEY);
      // Note: ozone.om.kerberos.keytab.file and ozone.om.kerberos.principal
      //  are not empty by default. The default values may or may not be valid.
      if (StringUtils.isBlank(omKerbPrinc)) {
        isS3MultiTenancyEnabled = false;
        logger.error("{} is required to enable S3 Multi-Tenancy but not set",
            OZONE_OM_KERBEROS_PRINCIPAL_KEY);
      }
      final String rangerPw = conf.get(OZONE_OM_KERBEROS_KEYTAB_FILE_KEY);
      if (StringUtils.isBlank(rangerPw)) {
        isS3MultiTenancyEnabled = false;
        logger.error("{} is required to enable S3 Multi-Tenancy but not set",
            OZONE_OM_KERBEROS_KEYTAB_FILE_KEY);
      }
      if (!(new File(rangerPw).isFile())) {
        logger.error("{} = '{}' file path doesn't exist or is not a file",
            OZONE_OM_KERBEROS_KEYTAB_FILE_KEY, rangerPw);
      }
    }

    if (!isS3MultiTenancyEnabled) {
      throw new RuntimeException("Failed to meet one or more requirements to "
          + "enable S3 Multi-Tenancy");
    }

    return true;
  }

  String OZONE_TENANT_RANGER_POLICY_DESCRIPTION =
      "Created by Ozone. WARNING: "
          + "Changes will be lost when this tenant is deleted.";

  String OZONE_TENANT_RANGER_ROLE_DESCRIPTION =
      "Managed by Ozone. WARNING: "
          + "Changes will be overridden. "
          + "Use Ozone tenant CLI to manage users in this tenant role instead.";

  /**
   * Returns default VolumeAccess policy given tenant and role names.
   */
  static Policy getDefaultVolumeAccessPolicy(
      String tenantId, String volumeName,
      String userRoleName, String adminRoleName)
      throws IOException {

    final String volumePolicyName = OMMultiTenantManager
        .getDefaultBucketNamespacePolicyName(tenantId);

    return new Policy.Builder()
        .setName(volumePolicyName)
        .addVolume(volumeName)
        .setDescription(OZONE_TENANT_RANGER_POLICY_DESCRIPTION)
        .addLabel(OZONE_TENANT_RANGER_POLICY_LABEL)
        .addRoleAcl(userRoleName, Arrays.asList(
            Acl.allow(READ), Acl.allow(LIST), Acl.allow(READ_ACL)))
        .addRoleAcl(adminRoleName, Collections.singletonList(Acl.allow(ALL)))
        .build();
  }

  /**
   * Returns default BucketAccess policy given tenant and user role name.
   */
  static Policy getDefaultBucketAccessPolicy(
      String tenantId, String volumeName,
      String userRoleName) throws IOException {
    final String bucketPolicyName = OMMultiTenantManager
        .getDefaultBucketPolicyName(tenantId);

    return new Policy.Builder()
        .setName(bucketPolicyName)
        .addVolume(volumeName)
        .addBucket("*")
        .setDescription(OZONE_TENANT_RANGER_POLICY_DESCRIPTION)
        .addLabel(OZONE_TENANT_RANGER_POLICY_LABEL)
        .addRoleAcl(userRoleName,
            Collections.singletonList(Acl.allow(CREATE)))
        .addUserAcl(new OzoneOwnerPrincipal().getName(),
            Collections.singletonList(Acl.allow(ALL)))
        .build();
  }

  AuthorizerLock getAuthorizerLock();
}
