/*
 * 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.cache;

import static org.junit.Assert.assertEquals;

import com.google.common.collect.Sets;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.apache.sentry.core.common.Authorizable;
import org.apache.sentry.core.common.utils.KeyValue;
import org.apache.sentry.core.common.utils.SentryConstants;
import org.apache.sentry.core.model.db.Column;
import org.apache.sentry.core.model.db.Database;
import org.apache.sentry.core.model.db.Server;
import org.apache.sentry.core.model.db.Table;
import org.apache.sentry.policy.common.CommonPrivilege;
import org.apache.sentry.policy.common.Privilege;
import org.junit.Ignore;
import org.junit.Test;

public class TestTreePrivilegeCache {
  @Test
  public void testListPrivilegesCaseSensitivity() {
    CommonPrivilege dbSelect = create(new KeyValue("Server", "Server1"),
      new KeyValue("db", "db1"), new KeyValue("action", "SELECT"));

    TreePrivilegeCache cache = new TreePrivilegeCache(Sets.newHashSet(dbSelect.toString()), null);
    assertEquals(1, cache.listPrivileges(null, null, null,
      new Server("server1"), new Database("db1")).size());
  }

  @Test
  public void testListPrivilegesWildCard() {
    CommonPrivilege t1D1Select = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "t1"), new KeyValue("action", "SELECT"));
    CommonPrivilege t1D2Select = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db2"), new KeyValue("table", "t1"), new KeyValue("action", "SELECT"));
    CommonPrivilege t2Select = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "t2"), new KeyValue("action", "SELECT"));
    CommonPrivilege wildCardTable = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "*"), new KeyValue("action", "SELECT"));
    CommonPrivilege allTable = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "ALL"), new KeyValue("action", "SELECT"));
    CommonPrivilege allDatabase = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "*"));
    CommonPrivilege colSelect = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "t1"), new KeyValue("column", "c1"), new KeyValue("action", "SELECT"));

    TreePrivilegeCache cache = new TreePrivilegeCache(Sets.newHashSet(t1D1Select.toString(),
      t1D2Select.toString(), t2Select.toString(), wildCardTable.toString(), allTable.toString(),
      allDatabase.toString(), colSelect.toString()), null);

    assertEquals(0, cache.listPrivileges(null, null, null, new Server("server1")).size());
    assertEquals(1, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db1")).size());
    assertEquals(1, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db2")).size());
    assertEquals(4, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db1"), new Table("t1")).size());
    assertEquals(5, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db1"), new Table("*")).size());
    assertEquals(5, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db1"), new Table("t1"), new Column("*")).size());
    assertEquals(6, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db1"), new Table("*"), new Column("*")).size());
    assertEquals(2, cache.listPrivileges(null, null, null, new Server("server1"), new Database("db2"), new Table("t1"), new Column("*")).size());
  }

  @Test
  public void testListPrivilegeObjectsWildCard() {
    CommonPrivilege t1D1Select = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "t1"), new KeyValue("action", "SELECT"));
    CommonPrivilege t1D2Select = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db2"), new KeyValue("table", "t1"), new KeyValue("action", "SELECT"));
    CommonPrivilege t2Select = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "t2"), new KeyValue("action", "SELECT"));
    CommonPrivilege wildCardTable = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "*"), new KeyValue("action", "SELECT"));
    CommonPrivilege allTable = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "ALL"), new KeyValue("action", "SELECT"));
    CommonPrivilege allDatabase = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "*"));
    CommonPrivilege colSelect = create(new KeyValue("Server", "server1"),
      new KeyValue("db", "db1"), new KeyValue("table", "t1"), new KeyValue("column", "c1"), new KeyValue("action", "SELECT"));

    TreePrivilegeCache cache = new TreePrivilegeCache(Sets.newHashSet(t1D1Select.toString(),
      t1D2Select.toString(), t2Select.toString(), wildCardTable.toString(), allTable.toString(),
      allDatabase.toString(), colSelect.toString()), null);

    assertEquals(0, cache.listPrivilegeObjects(null, null, null, new Server("server1")).size());
    assertEquals(1, cache.listPrivilegeObjects(null, null, null, new Server("server1"), new Database("db1")).size());
    assertEquals(1, cache.listPrivilegeObjects(null, null, null, new Server("server1"), new Database("db2")).size());
    assertEquals(4, cache.listPrivilegeObjects(null, null, null, new Server("server1"), new Database("db1"), new Table("t1")).size());
    assertEquals(5, cache.listPrivilegeObjects(null, null, null, new Server("server1"), new Database("db1"), new Table("*")).size());
    assertEquals(5, cache.listPrivilegeObjects(null, null, null, new Server("server1"), new Database("db1"), new Table("t1"), new Column("*")).size());
    assertEquals(6, cache.listPrivilegeObjects(null, null, null, new Server("server1"), new Database("db1"), new Table("*"), new Column("*")).size());
    assertEquals(2, cache.listPrivilegeObjects(null, null, null, new Server("server1"), new Database("db2"), new Table("t1"), new Column("*")).size());
  }

  @Test
  public void testListPrivilegesURI() {
    CommonPrivilege uri1Select = create(new KeyValue("Server", "server1"),
      new KeyValue("uri", "hdfs:///uri/path1"));
    CommonPrivilege uri2Select = create(new KeyValue("Server", "server1"),
      new KeyValue("uri", "hdfs:///uri/path2"));

    TreePrivilegeCache cache = new TreePrivilegeCache(Sets.newHashSet(uri1Select.toString(),
      uri2Select.toString()), null);

    assertEquals(2, cache.listPrivileges(null, null, null, new Server("server1")).size());
  }

  @Test
  @Ignore("This test should be run manually.")
  public void testListPrivilegesPerf() {

    Set<String> privileges = generatePrivilegeStrings(1000, 10);
    TreePrivilegeCache cache = new TreePrivilegeCache(privileges, null);
    List<Authorizable[]> authorizables = generateAuthoriables(12000, 10);

    long start = System.currentTimeMillis();
    for (Authorizable[] authorizableHierarchy : authorizables) {
      Set<String> priStrings = cache.listPrivileges(null, null, null, authorizableHierarchy);
      for (String priString : priStrings) {
        CommonPrivilege currPri = create(priString);
        currPri.getParts();
      }
    }
    long end = System.currentTimeMillis();

    System.out.println("TreePrivilegeCache - total time on list string: " + (end - start) + " ms");
  }

  @Test
  @Ignore("This test should be run manually.")
  public void testListPrivilegeObjectsPerf() {

    Set<String> privileges = generatePrivilegeStrings(1000, 10);
    TreePrivilegeCache cache = new TreePrivilegeCache(privileges, null);
    List<Authorizable[]> authorizables = generateAuthoriables(12000, 10);

    long start = System.currentTimeMillis();
    for (Authorizable[] authorizableHierarchy : authorizables) {
      Set<Privilege> privilegeSet = cache.listPrivilegeObjects(null, null, null, authorizableHierarchy);
      for (Privilege currPri : privilegeSet) {
        currPri.getParts();
      }
    }
    long end = System.currentTimeMillis();

    System.out.println("TreePrivilegeCache - total time on list obj: " + (end - start) + " ms");
  }

  Set<String> generatePrivilegeStrings(int dbCount, int tableCount) {
    Set<String> priStrings = new HashSet<>();
    for (int i = 0; i < dbCount; i ++) {
      for (int j = 0; j < tableCount; j ++) {
        String priString = "Server=server1->Database=db" + i + "->Table=table" + j;
        priStrings.add(priString);
      }
    }

    return priStrings;
  }

  List<Authorizable[]> generateAuthoriables(int dbCount, int tableCount) {
    List<Authorizable[]> authorizables = new ArrayList<>();

    for (int i = 0; i < dbCount; i ++) {
      for (int j = 0; j < tableCount; j ++) {
        Authorizable[] authorizable = new Authorizable[3];
        authorizable[0] = new Server("server1");
        authorizable[1] = new Database("db" + i);
        authorizable[2] = new Table("table" + j);

        authorizables.add(authorizable);
      }
    }

    return authorizables;
  }

  static CommonPrivilege create(KeyValue... keyValues) {
    return create(SentryConstants.AUTHORIZABLE_JOINER.join(keyValues));
  }

  static CommonPrivilege create(String s) {
    return new CommonPrivilege(s);
  }


}
