// 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.impala.catalog;

import org.apache.impala.authorization.AuthorizationPolicy;
import org.apache.impala.thrift.TCatalogObject;
import org.apache.impala.thrift.TCatalogObjectType;
import org.apache.impala.thrift.TPrincipalType;
import org.apache.impala.thrift.TPrivilege;
import org.apache.impala.thrift.TPrivilegeLevel;
import org.apache.impala.thrift.TPrivilegeScope;
import org.apache.log4j.Logger;

import com.google.common.base.Preconditions;

/**
 * Represents a privilege that has been granted to a principal in an authorization policy.
 * This class is thread safe.
 */
public class PrincipalPrivilege extends CatalogObjectImpl {
  private static final Logger LOG = Logger.getLogger(AuthorizationPolicy.class);
  private static final String AUTHORIZABLE_SEPARATOR = "->";
  private static final String KV_SEPARATOR = "=";
  private final TPrivilege privilege_;

  private PrincipalPrivilege(TPrivilege privilege) {
    privilege_ = Preconditions.checkNotNull(privilege);
  }

  public TPrivilege toThrift() { return privilege_; }
  public static PrincipalPrivilege fromThrift(TPrivilege privilege) {
    return new PrincipalPrivilege(privilege);
  }

  /**
   * Builds a privilege name for the given TPrivilege object. For simplicity, this name is
   * generated in a format that can be sent to the Sentry client to perform authorization
   * checks. The format is:
   * [ServerName=value]->[DbName=value]->[TableName=value]->[ColumnName=value]->[Action Granted=value]->[Grant Option=value]
   */
  public static String buildPrivilegeName(TPrivilege privilege) {
    StringBuilder privilegeName = new StringBuilder();
    Preconditions.checkNotNull(privilege);
    TPrivilegeScope scope = privilege.getScope();
    Preconditions.checkNotNull(scope);
    switch (scope) {
      case SERVER: {
        privilegeName.append("server")
            .append(KV_SEPARATOR)
            .append(privilege.getServer_name().toLowerCase());
        break;
      }
      case URI: {
        privilegeName.append("server")
            .append(KV_SEPARATOR)
            .append(privilege.getServer_name().toLowerCase());
        privilegeName.append(AUTHORIZABLE_SEPARATOR);
        // (IMPALA-2695) URIs are case sensitive
        privilegeName.append("uri")
            .append(KV_SEPARATOR)
            .append(privilege.getUri());
        break;
      }
      case DATABASE: {
        privilegeName.append("server")
            .append(KV_SEPARATOR)
            .append(privilege.getServer_name().toLowerCase());
        privilegeName.append(AUTHORIZABLE_SEPARATOR);
        privilegeName.append("db")
            .append(KV_SEPARATOR)
            .append(privilege.getDb_name().toLowerCase());
        break;
      }
      case TABLE: {
        privilegeName.append("server")
            .append(KV_SEPARATOR)
            .append(privilege.getServer_name().toLowerCase());
        privilegeName.append(AUTHORIZABLE_SEPARATOR);
        privilegeName.append("db")
            .append(KV_SEPARATOR)
            .append(privilege.getDb_name().toLowerCase());
        privilegeName.append(AUTHORIZABLE_SEPARATOR);
        privilegeName.append("table")
            .append(KV_SEPARATOR)
            .append(privilege.getTable_name().toLowerCase());
        break;
      }
      case COLUMN: {
        privilegeName.append("server")
            .append(KV_SEPARATOR)
            .append(privilege.getServer_name().toLowerCase());
        privilegeName.append(AUTHORIZABLE_SEPARATOR);
        privilegeName.append("db")
            .append(KV_SEPARATOR)
            .append(privilege.getDb_name().toLowerCase());
        privilegeName.append(AUTHORIZABLE_SEPARATOR);
        privilegeName.append("table")
            .append(KV_SEPARATOR)
            .append(privilege.getTable_name().toLowerCase());
        privilegeName.append(AUTHORIZABLE_SEPARATOR);
        privilegeName.append("column")
            .append(KV_SEPARATOR)
            .append(privilege.getColumn_name().toLowerCase());
        break;
      }
      default: {
        throw new UnsupportedOperationException(
            "Unknown privilege scope: " + scope.toString());
      }
    }

    // The ALL privilege is always implied and does not need to be included as part
    // of the name.
    if (privilege.getPrivilege_level() != TPrivilegeLevel.ALL) {
      privilegeName.append(AUTHORIZABLE_SEPARATOR);
      privilegeName.append("action")
          .append(KV_SEPARATOR)
          .append(privilege.getPrivilege_level().toString().toLowerCase());
    }
    privilegeName.append(AUTHORIZABLE_SEPARATOR);
    privilegeName.append("grantoption")
        .append(KV_SEPARATOR)
        .append(privilege.isHas_grant_opt());
    return privilegeName.toString();
  }

  /**
   * Copies the given privilege and sets the has grant option.
   */
  public static TPrivilege copyPrivilegeWithGrant(TPrivilege privilege,
      boolean hasGrantOption) {
    TPrivilege copy = privilege.deepCopy();
    return copy.setHas_grant_opt(hasGrantOption);
  }

  @Override
  public TCatalogObjectType getCatalogObjectType() {
    return TCatalogObjectType.PRIVILEGE;
  }
  @Override
  public String getName() { return buildPrivilegeName(privilege_); }
  public int getPrincipalId() { return privilege_.getPrincipal_id(); }
  public TPrincipalType getPrincipalType() { return privilege_.getPrincipal_type(); }

  @Override
  protected void setTCatalogObject(TCatalogObject catalogObject) {
    catalogObject.setPrivilege(toThrift());
  }

  // The time this principal was created. Used to quickly check if the same privilege
  // was dropped and re-created. Assumes a principal will not be created + dropped +
  // created in less than 1ms. Returns -1 if create_time_ms was not set for the privilege.
  public long getCreateTimeMs() {
    return privilege_.isSetCreate_time_ms() ? privilege_.getCreate_time_ms() : -1L;
  }
}
