/**
 * 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.sentry.provider.db.generic.service.persistent;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.jdo.PersistenceManager;
import javax.jdo.Query;

import org.apache.sentry.SentryUserException;
import org.apache.sentry.core.common.Action;
import org.apache.sentry.core.common.Authorizable;
import org.apache.sentry.core.common.BitFieldAction;
import org.apache.sentry.core.common.BitFieldActionFactory;
import org.apache.sentry.core.model.search.SearchActionFactory;
import org.apache.sentry.provider.db.generic.service.persistent.PrivilegeObject.Builder;
import org.apache.sentry.provider.db.service.model.MSentryGMPrivilege;
import org.apache.sentry.provider.db.service.model.MSentryPrivilege;
import org.apache.sentry.provider.db.service.model.MSentryRole;

import com.google.common.base.Joiner;
import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

/**
 * This class used do some operations related privilege and make the results
 * persistence
 */
public class PrivilegeOperatePersistence {
  private static final Map<String, BitFieldActionFactory> actionFactories = Maps.newHashMap();
  static{
    actionFactories.put("solr", new SearchActionFactory());
  }

  public boolean checkPrivilegeOption(Set<MSentryRole> roles, PrivilegeObject privilege, PersistenceManager pm) {
    MSentryGMPrivilege requestPrivilege = convertToPrivilege(privilege);
    boolean hasGrant = false;
    //get persistent privileges by roles
    Query query = pm.newQuery(MSentryGMPrivilege.class);
    StringBuilder filters = new StringBuilder();
    if ((roles != null) && (roles.size() > 0)) {
      query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
      List<String> rolesFiler = new LinkedList<String>();
      for (MSentryRole role : roles) {
        rolesFiler.add("role.roleName == \"" + role.getRoleName() + "\" ");
      }
      filters.append("roles.contains(role) " + "&& (" + Joiner.on(" || ").join(rolesFiler) + ")");
    }
    query.setFilter(filters.toString());

    List<MSentryGMPrivilege> tPrivileges = (List<MSentryGMPrivilege>)query.execute();
    for (MSentryGMPrivilege tPrivilege : tPrivileges) {
      if (tPrivilege.getGrantOption() && tPrivilege.implies(requestPrivilege)) {
        hasGrant = true;
        break;
      }
    }
    return hasGrant;
  }
  public void grantPrivilege(PrivilegeObject privilege,MSentryRole role, PersistenceManager pm) throws SentryUserException {
    MSentryGMPrivilege mPrivilege = convertToPrivilege(privilege);
    grantRolePartial(mPrivilege, role, pm);
  }

  private void grantRolePartial(MSentryGMPrivilege grantPrivilege,
      MSentryRole role,PersistenceManager pm) {
    /**
     * If Grant is for ALL action and other actions belongs to ALL action already exists..
     * need to remove it and GRANT ALL action
     */
    String component = grantPrivilege.getComponentName();
    BitFieldAction action = getAction(component, grantPrivilege.getAction());
    BitFieldAction allAction = getAction(component, Action.ALL);

    if (action.implies(allAction)) {
      /**
       * ALL action is a multi-bit set action that includes some actions such as INSERT,SELECT and CREATE.
       */
      List<? extends BitFieldAction> actions = getActionFactory(component).getActionsByCode(allAction.getActionCode());
      for (BitFieldAction ac : actions) {
        grantPrivilege.setAction(ac.getValue());
        MSentryGMPrivilege existPriv = getPrivilege(grantPrivilege, pm);
        if ((existPriv != null) && (role.getGmPrivileges().contains(existPriv))) {
          /**
           * force to load all roles related this privilege
           * avoid the lazy-loading risk,such as:
           * if the roles field of privilege aren't loaded, then the roles is a empty set
           * privilege.removeRole(role) and pm.makePersistent(privilege)
           * will remove other roles that shouldn't been removed
           */
          pm.retrieve(existPriv);
          existPriv.removeRole(role);
          pm.makePersistent(existPriv);
        }
      }
    } else {
      /**
       * If ALL Action already exists..
       * do nothing.
       */
      grantPrivilege.setAction(allAction.getValue());
      MSentryGMPrivilege allPrivilege = getPrivilege(grantPrivilege, pm);
      if ((allPrivilege != null) && (role.getGmPrivileges().contains(allPrivilege))) {
        return;
      }
    }

    /**
     * restore the action
     */
    grantPrivilege.setAction(action.getValue());
    /**
     * check the privilege is exist or not
     */
    MSentryGMPrivilege mPrivilege = getPrivilege(grantPrivilege, pm);
    if (mPrivilege == null) {
      mPrivilege = grantPrivilege;
    }
    mPrivilege.appendRole(role);
    pm.makePersistent(mPrivilege);
  }


  public void revokePrivilege(PrivilegeObject privilege,MSentryRole role, PersistenceManager pm) throws SentryUserException {
    MSentryGMPrivilege mPrivilege = getPrivilege(convertToPrivilege(privilege), pm);
    if (mPrivilege == null) {
      mPrivilege = convertToPrivilege(privilege);
    } else {
      mPrivilege = (MSentryGMPrivilege) pm.detachCopy(mPrivilege);
    }

    Set<MSentryGMPrivilege> privilegeGraph = Sets.newHashSet();
    privilegeGraph.addAll(populateIncludePrivileges(Sets.newHashSet(role), mPrivilege, pm));

    /**
     * Get the privilege graph
     * populateIncludePrivileges will get the privileges that needed revoke
     */
    for (MSentryGMPrivilege persistedPriv : privilegeGraph) {
      /**
       * force to load all roles related this privilege
       * avoid the lazy-loading risk,such as:
       * if the roles field of privilege aren't loaded, then the roles is a empty set
       * privilege.removeRole(role) and pm.makePersistent(privilege)
       * will remove other roles that shouldn't been removed
       */
      revokeRolePartial(mPrivilege, persistedPriv, role, pm);
    }
    pm.makePersistent(role);
  }

  /**
   * Explore Privilege graph and collect privileges that are belong to the specific privilege
   */
  @SuppressWarnings("unchecked")
  private Set<MSentryGMPrivilege> populateIncludePrivileges(Set<MSentryRole> roles,
      MSentryGMPrivilege parent, PersistenceManager pm) {
    Set<MSentryGMPrivilege> childrens = Sets.newHashSet();

    Query query = pm.newQuery(MSentryGMPrivilege.class);
    StringBuilder filters = new StringBuilder();
    //add populateIncludePrivilegesQuery
    filters.append(MSentryGMPrivilege.populateIncludePrivilegesQuery(parent));
    // add filter for role names
    if ((roles != null) && (roles.size() > 0)) {
      query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
      List<String> rolesFiler = new LinkedList<String>();
      for (MSentryRole role : roles) {
        rolesFiler.add("role.roleName == \"" + role.getRoleName() + "\" ");
      }
      filters.append("&& roles.contains(role) " + "&& (" + Joiner.on(" || ").join(rolesFiler) + ")");
    }
    query.setFilter(filters.toString());

    List<MSentryGMPrivilege> privileges = (List<MSentryGMPrivilege>)query.execute();
    childrens.addAll(privileges);
    return childrens;
  }

  /**
   * Roles can be granted multi-bit set action like ALL action on resource object.
   * Take solr component for example, When a role has been granted ALL action but
   * QUERY or UPDATE or CREATE are revoked, we need to remove the ALL
   * privilege and add left privileges like UPDATE and CREATE(QUERY was revoked) or
   * QUERY and UPDATE(CREATEE was revoked).
   */
  private void revokeRolePartial(MSentryGMPrivilege revokePrivilege,
      MSentryGMPrivilege persistedPriv, MSentryRole role,
      PersistenceManager pm) {
    String component = revokePrivilege.getComponentName();
    BitFieldAction revokeaction = getAction(component, revokePrivilege.getAction());
    BitFieldAction persistedAction = getAction(component, persistedPriv.getAction());
    BitFieldAction allAction = getAction(component, Action.ALL);

    if (revokeaction.implies(allAction)) {
      /**
       * if revoke action is ALL, directly revoke its children privileges and itself
       */
      persistedPriv.removeRole(role);
      pm.makePersistent(persistedPriv);
    } else {
      /**
       * if persisted action is ALL, it only revoke the requested action and left partial actions
       * like the requested action is SELECT, the UPDATE and CREATE action are left
       */
      if (persistedAction.implies(allAction)) {
        /**
         * revoke the ALL privilege
         */
        persistedPriv.removeRole(role);
        pm.makePersistent(persistedPriv);

        List<? extends BitFieldAction> actions = getActionFactory(component).getActionsByCode(allAction.getActionCode());
        for (BitFieldAction ac: actions) {
          if (ac.getActionCode() != revokeaction.getActionCode()) {
            /**
             * grant the left privileges to role
             */
            MSentryGMPrivilege tmpPriv = new MSentryGMPrivilege(persistedPriv);
            tmpPriv.setAction(ac.getValue());
            MSentryGMPrivilege leftPersistedPriv = getPrivilege(tmpPriv, pm);
            if (leftPersistedPriv == null) {
              //leftPersistedPriv isn't exist
              leftPersistedPriv = tmpPriv;
              role.appendGMPrivilege(leftPersistedPriv);
            }
            leftPersistedPriv.appendRole(role);
            pm.makePersistent(leftPersistedPriv);
          }
        }
      } else if (revokeaction.implies(persistedAction)) {
        /**
         * if the revoke action is equal to the persisted action and they aren't ALL action
         * directly remove the role from privilege
         */
        persistedPriv.removeRole(role);
        pm.makePersistent(persistedPriv);
      } else {
        /**
         * if the revoke action is not equal to the persisted action,
         * do nothing
         */
      }
    }
  }

  /**
   * Drop any role related to the requested privilege and its children privileges
   */
  public void dropPrivilege(PrivilegeObject privilege,PersistenceManager pm) {
    MSentryGMPrivilege requestPrivilege = convertToPrivilege(privilege);

    if (Strings.isNullOrEmpty(privilege.getAction())) {
      requestPrivilege.setAction(getAction(privilege.getComponent(), Action.ALL).getValue());
    }
    /**
     * Get the privilege graph
     * populateIncludePrivileges will get the privileges that need dropped,
     */
    Set<MSentryGMPrivilege> privilegeGraph = Sets.newHashSet();
    privilegeGraph.addAll(populateIncludePrivileges(null, requestPrivilege, pm));

    for (MSentryGMPrivilege mPrivilege : privilegeGraph) {
      /**
       * force to load all roles related this privilege
       * avoid the lazy-loading
       */
      pm.retrieve(mPrivilege);
      Set<MSentryRole> roles = mPrivilege.getRoles();
      for (MSentryRole role : roles) {
        revokeRolePartial(requestPrivilege, mPrivilege, role, pm);
      }
    }
  }

  private MSentryGMPrivilege convertToPrivilege(PrivilegeObject privilege) {
    return new MSentryGMPrivilege(privilege.getComponent(),
        privilege.getService(), privilege.getAuthorizables(),
        privilege.getAction(), privilege.getGrantOption());
  }

  private MSentryGMPrivilege getPrivilege(MSentryGMPrivilege privilege, PersistenceManager pm) {
    Query query = pm.newQuery(MSentryGMPrivilege.class);
    query.setFilter(MSentryGMPrivilege.toQuery(privilege));
    query.setUnique(true);
    return (MSentryGMPrivilege)query.execute();
  }

  @SuppressWarnings("unchecked")
  public Set<PrivilegeObject> getPrivilegesByRole(Set<MSentryRole> roles, PersistenceManager pm) {
    Set<PrivilegeObject> privileges = Sets.newHashSet();
    if ((roles == null) || (roles.size() == 0)) {
      return privileges;
    }
    Query query = pm.newQuery(MSentryGMPrivilege.class);
    StringBuilder filters = new StringBuilder();
    // add filter for role names
    query.declareVariables("org.apache.sentry.provider.db.service.model.MSentryRole role");
    List<String> rolesFiler = new LinkedList<String>();
    for (MSentryRole role : roles) {
      rolesFiler.add("role.roleName == \"" + role.getRoleName() + "\" ");
    }
    filters.append("roles.contains(role) " + "&& (" + Joiner.on(" || ").join(rolesFiler) + ")");

    query.setFilter(filters.toString());
    List<MSentryGMPrivilege> mPrivileges = (List<MSentryGMPrivilege>) query.execute();
    if ((mPrivileges == null) || (mPrivileges.size() ==0)) {
      return privileges;
    }
    for (MSentryGMPrivilege mPrivilege : mPrivileges) {
      privileges.add(new Builder()
                               .setComponent(mPrivilege.getComponentName())
                               .setService(mPrivilege.getServiceName())
                               .setAction(mPrivilege.getAction())
                               .setAuthorizables(mPrivilege.getAuthorizables())
                               .withGrantOption(mPrivilege.getGrantOption())
                               .build());
    }
    return privileges;
  }

  public Set<PrivilegeObject> getPrivilegesByProvider(String component,
      String service, Set<MSentryRole> roles,
      List<? extends Authorizable> authorizables, PersistenceManager pm) {
    Set<PrivilegeObject> privileges = Sets.newHashSet();
    if ((roles == null) || (roles.size() == 0)) return privileges;

    MSentryGMPrivilege parentPrivilege = new MSentryGMPrivilege(component, service, authorizables, null, null);
    Set<MSentryGMPrivilege> privilegeGraph = Sets.newHashSet();
    privilegeGraph.addAll(populateIncludePrivileges(roles, parentPrivilege, pm));

    for (MSentryGMPrivilege mPrivilege : privilegeGraph) {
      privileges.add(new Builder()
                               .setComponent(mPrivilege.getComponentName())
                               .setService(mPrivilege.getServiceName())
                               .setAction(mPrivilege.getAction())
                               .setAuthorizables(mPrivilege.getAuthorizables())
                               .withGrantOption(mPrivilege.getGrantOption())
                               .build());
    }
    return privileges;
  }


  public void renamePrivilege(String component, String service,
      List<? extends Authorizable> oldAuthorizables, List<? extends Authorizable> newAuthorizables,
      String grantorPrincipal, PersistenceManager pm)
      throws SentryUserException {
    MSentryGMPrivilege oldPrivilege = new MSentryGMPrivilege(component, service, oldAuthorizables, null, null);
    oldPrivilege.setAction(getAction(component,Action.ALL).getValue());
    /**
     * Get the privilege graph
     * populateIncludePrivileges will get the old privileges that need dropped
     */
    Set<MSentryGMPrivilege> privilegeGraph = Sets.newHashSet();
    privilegeGraph.addAll(populateIncludePrivileges(null, oldPrivilege, pm));

    for (MSentryGMPrivilege dropPrivilege : privilegeGraph) {
      /**
       * construct the new privilege needed to add
       */
      List<Authorizable> authorizables = new ArrayList<Authorizable>(
          dropPrivilege.getAuthorizables());
      for (int i = 0; i < newAuthorizables.size(); i++) {
        authorizables.set(i, newAuthorizables.get(i));
      }
      MSentryGMPrivilege newPrivilge = new MSentryGMPrivilege(
          component,service, authorizables, dropPrivilege.getAction(),
          dropPrivilege.getGrantOption());

      /**
       * force to load all roles related this privilege
       * avoid the lazy-loading
       */
      pm.retrieve(dropPrivilege);

      Set<MSentryRole> roles = dropPrivilege.getRoles();
      for (MSentryRole role : roles) {
        revokeRolePartial(oldPrivilege, dropPrivilege, role, pm);
        grantRolePartial(newPrivilge, role, pm);
      }
    }
  }

  public static BitFieldAction getAction(String component, String name) {
    BitFieldActionFactory actionFactory = getActionFactory(component);
    BitFieldAction action = actionFactory.getActionByName(name);
    if (action == null) {
      throw new RuntimeException("can't get BitFieldAction for name:" + name);
    }
    return action;
  }

  public static BitFieldActionFactory getActionFactory(String component) {
    BitFieldActionFactory actionFactory = actionFactories.get(component.toLowerCase());
    if (actionFactory == null) {
      throw new RuntimeException("can't get actionFactory for component:" + component);
    }
    return actionFactory;
  }
}
