/**
 * 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.tests.e2e.dbprovider;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;

import org.apache.sentry.tests.e2e.hive.AbstractTestWithStaticConfiguration;
import org.junit.After;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import com.google.common.collect.Lists;
import com.google.common.io.Resources;

public class TestDbPrivilegeCleanupOnDrop extends
    AbstractTestWithStaticConfiguration {

  private final static int SHOW_GRANT_TABLE_POSITION = 2;
  private final static int SHOW_GRANT_DB_POSITION = 1;

  private final String SINGLE_TYPE_DATA_FILE_NAME = "kv1.dat";

  private final static String tableName1 = "tb_1";
  private final static String tableName2 = "tb_2";
  private final static String tableName3 = "tb_3";
  private final static String tableName4 = "tb_4";
  private final static String renameTag = "_new";

  @BeforeClass
  public static void setupTestStaticConfiguration() throws Exception {
    useSentryService = true;
    if (!setMetastoreListener) {
      setMetastoreListener = true;
    }
    AbstractTestWithStaticConfiguration.setupTestStaticConfiguration();
  }

  @Override
  @Before
  public void setup() throws Exception {
    super.setupAdmin();
    super.setup();
    // context = createContext();
    File dataFile = new File(dataDir, SINGLE_TYPE_DATA_FILE_NAME);
    FileOutputStream to = new FileOutputStream(dataFile);
    Resources.copy(Resources.getResource(SINGLE_TYPE_DATA_FILE_NAME), to);
    to.close();
  }

  @After
  public void tearDown() throws Exception {
    if (context != null) {
      context.close();
    }
  }

  /**
   * drop table and verify that the no privileges are referring to it drop db
   * and verify that the no privileges are referring to it drop db cascade
   * verify that the no privileges are referring to db and tables under it
   *
   * @throws Exception
   */
  @Test
  public void testDropObjects() throws Exception {
    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);

    setupRoles(statement); // create required roles
    setupDbObjects(statement); // create test DBs and Tables
    setupPrivileges(statement); // setup privileges for USER1
    dropDbObjects(statement); // drop objects
    verifyPrivilegesDropped(statement); // verify privileges are removed

    statement.close();
    connection.close();
  }

  /**
   * Return the remaining rows of the current resultSet
   * Cautiously it will modify the cursor position of the resultSet
   *
   */
  private void assertRemainingRows(ResultSet resultSet, int expected) throws SQLException{
    int count = 0;
    while(resultSet.next()) {
      count++;
    }
    assertThat(count, is(expected));
  }

  /**
   * drop table and verify that the no privileges are referring to it drop db
   * and verify that the no privileges are referring to it drop db cascade
   * verify that the no privileges are referring to db and tables under it
   *
   * @throws Exception
   */
  @Test
  public void testReCreateObjects() throws Exception {
    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);
    setupRoles(statement); // create required roles
    setupDbObjects(statement); // create test DBs and Tables
    setupPrivileges(statement); // setup privileges for USER1
    dropDbObjects(statement); // drop DB and tables

    setupDbObjects(statement); // recreate same DBs and tables
    verifyPrivilegesDropped(statement); // verify the stale privileges removed
  }

  /**
   * rename table and verify that the no privileges are referring to it old table
   * verify that the same privileges are created for the new table name
   *
   * @throws Exception
   */
  @Test
  public void testRenameTables() throws Exception {
    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);

    setupRoles(statement); // create required roles
    setupDbObjects(statement); // create test DBs and Tables
    setupPrivileges(statement); // setup privileges for USER1

    // verify privileges on the created tables
    statement.execute("USE " + DB2);
    verifyTablePrivilegeExist(statement,
        Lists.newArrayList("select_tbl1", "insert_tbl1", "all_tbl1"),
        tableName1);
    verifyTablePrivilegeExist(statement, Lists.newArrayList("all_tbl2"),
        tableName2);

    renameTables(statement); // alter tables to rename

    // verify privileges removed for old tables
    verifyTablePrivilegesDropped(statement);

    // verify privileges created for new tables
    statement.execute("USE " + DB2);
    verifyTablePrivilegeExist(statement,
        Lists.newArrayList("select_tbl1", "insert_tbl1", "all_tbl1"),
        tableName1 + renameTag);
    verifyTablePrivilegeExist(statement, Lists.newArrayList("all_tbl2"),
        tableName2 + renameTag);

    statement.close();
    connection.close();
  }

  /**
   * After we drop/rename table, we will drop/rename all privileges(ALL,SELECT,INSERT,ALTER,DROP...)
   * from this role
   *
   * @throws Exception
   */
  @Test
  public void testDropAndRenameWithMultiAction() throws Exception {
    Connection connection = context.createConnection(ADMIN1);
    Statement statement = context.createStatement(connection);
    statement.execute("CREATE ROLE user_role");
    statement.execute("GRANT ROLE user_role TO GROUP " + USERGROUP1);

    statement.execute("CREATE DATABASE " + DB1);
    statement.execute("USE " + DB1);
    statement.execute("CREATE TABLE t1 (c1 string)");

    // Grant SELECT/INSERT/DROP/ALTER to TABLE t1
    statement.execute("GRANT SELECT ON TABLE t1 TO ROLE user_role");
    statement.execute("GRANT INSERT ON TABLE t1 TO ROLE user_role");
    statement.execute("GRANT ALTER ON TABLE t1 TO ROLE user_role");
    statement.execute("GRANT DROP ON TABLE t1 TO ROLE user_role");
    // For rename, grant CREATE to DB1
    statement.execute("GRANT CREATE ON DATABASE " + DB1 + " TO ROLE user_role");

    // After rename table t1 to t2, user_role will have no permission to drop t1
    connection = context.createConnection(USER1_1);
    statement = context.createStatement(connection);
    statement.execute("USE " + DB1);
    statement.execute("ALTER TABLE t1 RENAME TO t2");
    context.assertSentrySemanticException(statement, "drop table t1", semanticException);

    // After rename table t1 to t2, user_role should have permission to drop t2
    statement.execute("drop table t2");
    ResultSet resultSet = statement.executeQuery("SHOW GRANT ROLE user_role");
    // user_role will revoke all privilege from table t2, only remain CREATE on db_1
    assertRemainingRows(resultSet, 1);

    statement.close();
    connection.close();
  }

  // Create test roles
  private void setupRoles(Statement statement) throws Exception {
    statement.execute("CREATE ROLE all_db1");
    statement.execute("CREATE ROLE read_db1");
    statement.execute("CREATE ROLE select_tbl1");
    statement.execute("CREATE ROLE insert_tbl1");
    statement.execute("CREATE ROLE all_tbl1");
    statement.execute("CREATE ROLE all_tbl2");
    statement.execute("CREATE ROLE all_prod");

    statement.execute("GRANT ROLE all_db1, read_db1, select_tbl1, insert_tbl1,"
        + " all_tbl1, all_tbl2, all_prod to GROUP " + USERGROUP1);

    statement.execute("DROP DATABASE IF EXISTS " + DB1 + " CASCADE");
    statement.execute("DROP DATABASE IF EXISTS " + DB2 + " CASCADE");
  }

  // create test DBs and Tables
  private void setupDbObjects(Statement statement) throws Exception {
    statement.execute("CREATE DATABASE " + DB1);
    statement.execute("CREATE DATABASE " + DB2);
    statement.execute("create table " + DB2 + "." + tableName1
        + " (under_col int comment 'the under column', value string)");
    statement.execute("create table " + DB2 + "." + tableName2
        + " (under_col int comment 'the under column', value string)");
    statement.execute("create table " + DB1 + "." + tableName3
        + " (under_col int comment 'the under column', value string)");
    statement.execute("create table " + DB1 + "." + tableName4
        + " (under_col int comment 'the under column', value string)");
  }

  // Create privileges on DB and Tables
  private void setupPrivileges(Statement statement) throws Exception {
    statement.execute("GRANT ALL ON DATABASE " + DB1 + " TO ROLE all_db1");
    statement.execute("GRANT SELECT ON DATABASE " + DB1
        + " TO ROLE read_db1");
    statement.execute("GRANT ALL ON DATABASE " + DB2 + " TO ROLE all_prod");
    statement.execute("USE " + DB2);
    statement.execute("GRANT SELECT ON TABLE " + tableName1
        + " TO ROLE select_tbl1");
    statement.execute("GRANT INSERT ON TABLE " + tableName1
        + " TO ROLE insert_tbl1");
    statement.execute("GRANT ALL ON TABLE " + tableName1 + " TO ROLE all_tbl1");
    statement.execute("GRANT ALL ON TABLE " + tableName2 + " TO ROLE all_tbl2");
  }

  // Drop test DBs and Tables
  private void dropDbObjects(Statement statement) throws Exception {
    statement.execute("DROP TABLE " + DB2 + "." + tableName1);
    statement.execute("DROP TABLE " + DB2 + "." + tableName2);
    statement.execute("DROP DATABASE " + DB2);
    statement.execute("DROP DATABASE " + DB1 + " CASCADE");
  }

  // rename tables
  private void renameTables(Statement statement) throws Exception {
    statement.execute("USE " + DB2);
    statement.execute("ALTER TABLE " + tableName1 + " RENAME TO " + tableName1
        + renameTag);
    statement.execute("ALTER TABLE " + tableName2 + " RENAME TO " + tableName2
        + renameTag);
    statement.execute("USE " + DB1);
    statement.execute("ALTER TABLE " + tableName3 + " RENAME TO " + tableName3
        + renameTag);
    statement.execute("ALTER TABLE " + tableName4 + " RENAME TO " + tableName4
        + renameTag);
  }

  // verify all the test privileges are dropped as we drop the objects
  private void verifyPrivilegesDropped(Statement statement)
      throws Exception {
    verifyDbPrivilegesDropped(statement);
    verifyTablePrivilegesDropped(statement);
  }

  // verify all the test privileges are dropped as we drop the objects
  private void verifyTablePrivilegesDropped(Statement statement)
      throws Exception {
    List<String> roles = getRoles(statement);
    verifyPrivilegeDropped(statement, roles, tableName1,
        SHOW_GRANT_TABLE_POSITION);
    verifyPrivilegeDropped(statement, roles, tableName2,
        SHOW_GRANT_TABLE_POSITION);
    verifyPrivilegeDropped(statement, roles, tableName3,
        SHOW_GRANT_TABLE_POSITION);
    verifyPrivilegeDropped(statement, roles, tableName4,
        SHOW_GRANT_TABLE_POSITION);

  }

  // verify all the test privileges are dropped as we drop the objects
  private void verifyDbPrivilegesDropped(Statement statement) throws Exception {
    List<String> roles = getRoles(statement);
    verifyPrivilegeDropped(statement, roles, DB2, SHOW_GRANT_DB_POSITION);
    verifyPrivilegeDropped(statement, roles, DB1, SHOW_GRANT_DB_POSITION);

  }

  // verify given table/DB has no longer permissions
  private void verifyPrivilegeDropped(Statement statement, List<String> roles,
      String objectName, int resultPos) throws Exception {
    for (String roleName : roles) {
      ResultSet resultSet = statement.executeQuery("SHOW GRANT ROLE "
          + roleName);
      while (resultSet.next()) {
        String returned = resultSet.getString(resultPos);
        assertFalse("value " + objectName + " shouldn't be detected, but actually " + returned + " is found from resultSet",
                objectName.equalsIgnoreCase(returned));
      }
      resultSet.close();
    }
  }

  // verify given table is part of the role
  private void verifyTablePrivilegeExist(Statement statement,
      List<String> roles, String tableName) throws Exception {
    for (String roleName : roles) {
      ResultSet resultSet = statement.executeQuery("SHOW GRANT ROLE "
          + roleName + " ON TABLE " + tableName);
      assertTrue(resultSet.next());
      resultSet.close();
    }
  }

  private List<String> getRoles(Statement statement) throws Exception {
    ArrayList<String> roleList = Lists.newArrayList();
    ResultSet resultSet = statement.executeQuery("SHOW ROLES ");
    while (resultSet.next()) {
      roleList.add(resultSet.getString(1));
    }
    return roleList;
  }
}
