/*
 * 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.drill.exec.coord.zk;

import com.typesafe.config.ConfigValueFactory;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.ACLProvider;
import org.apache.curator.retry.RetryNTimes;
import org.apache.curator.test.TestingServer;
import org.apache.drill.categories.SecurityTest;
import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.common.scanner.ClassPathScanner;
import org.apache.drill.common.scanner.persistence.ScanResult;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.server.BootStrapContext;
import org.apache.drill.exec.server.options.SystemOptionManager;
import org.apache.drill.test.BaseTest;
import org.apache.zookeeper.data.ACL;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import java.nio.charset.StandardCharsets;
import java.util.List;

@Ignore("See DRILL-6823")
@Category(SecurityTest.class)
public class TestZKACL extends BaseTest {

  private TestingServer server;
  private final static String cluster_config_znode = "test-cluster_config_znode";
  private final static byte[] cluster_config_data = "drill-node-1".getBytes(StandardCharsets.UTF_8);
  private final static String drill_zk_root = "drill-test-drill_zk_root";
  private final static String drill_cluster_name = "test-drillbits";
  private static final String drillClusterPath = "/" + drill_zk_root + "/" + drill_cluster_name;
  private static final RetryPolicy retryPolicy = new RetryNTimes(1, 1000);

  private static final String drillUDFName = "test-udfs";
  private final static byte[] udf_data = "test-udf-1".getBytes(StandardCharsets.UTF_8);
  private static final String drillUDFPath = "/" + drill_zk_root + "/" + drillUDFName;
  private static ACLProvider aclProviderDelegate;

  private static CuratorFramework client;

  @Before
  public void setUp() throws Exception {
    System.setProperty("zookeeper.authProvider.1", "org.apache.zookeeper.server.auth.SASLAuthenticationProvider");
    String configPath = (ClassLoader.getSystemResource("zkacltest.conf")).getPath();
    System.setProperty("java.security.auth.login.config", configPath);
    server = new TestingServer();


    final DrillConfig config = new DrillConfig(DrillConfig.create().withValue(ExecConstants.ZK_ACL_PROVIDER,
            ConfigValueFactory.fromAnyRef("creator-all")
    ).withValue(ExecConstants.ZK_APPLY_SECURE_ACL, ConfigValueFactory.fromAnyRef(true)));

    final ScanResult result = ClassPathScanner.fromPrescan(config);
    final BootStrapContext bootStrapContext =
            new BootStrapContext(config, SystemOptionManager.createDefaultOptionDefinitions(), result);
    aclProviderDelegate = ZKACLProviderFactory.getACLProvider(config, drillClusterPath, bootStrapContext);

    server.start();

    client =  CuratorFrameworkFactory.builder().
            retryPolicy(retryPolicy).
            connectString(server.getConnectString()).
            aclProvider(aclProviderDelegate).
            build();
    client.start();
  }

  /**
   * Test ACLs on znodes required to discover the cluster
   *
   * ZK libraries only supports one client instance per-machine per-server and it is cached.
   * This test will fail when run after other ZK tests that setup the client in a way that will cause this test to fail
   */

  @Test
  public void testClusterDiscoveryPaths() {
    try {
      String path = PathUtils.join(drillClusterPath, cluster_config_znode);
      client.create().creatingParentsIfNeeded().forPath(path, cluster_config_data);
      List<ACL> remoteACLs = client.getACL().forPath(path);
      List<ACL> desiredACLs = ((ZKACLProviderDelegate) aclProviderDelegate).aclProvider.getDrillAclForPath(drillClusterPath);

      // Check the ACLs
      for (ACL remote : remoteACLs) {
        boolean found = false;
        for (ACL desired : desiredACLs) {
          // desiredACL list is READ_ACL_UNSAFE (READ, WORLD_ANYONE) + CREATOR_ALL_ACL(ALL, AUTH)
          // AUTH in CREATOR_ALL would translate to SASL, username. Hence the replacement
          // Note: The username("testuser1") should match the username in java.security.auth.login.config
          found = desired.toString().equals(remote.toString().replace("sasl", "auth").replace("testuser1", ""));

          if (found) { break; }
        }
        Assert.assertTrue(found);
      }
      // check if the data can be read
      byte[] actual = client.getData().forPath(path);
      Assert.assertArrayEquals("testClusterDiscoveryPaths data mismatch", cluster_config_data, actual);

    } catch (Exception e) {
      throw new IllegalStateException("testClusterDiscoveryPaths failed");
    }
  }

  /**
   * Test ACLs on znodes other than ones required to discover the cluster
   *
   * ZK libraries only supports one client instance per-machine per-server and it is cached.
   * This test will fail when run after other ZK tests that setup the client in a way that will cause this test to fail
   */
  @Test
  public void testNonClusterDiscoveryPaths() {
    try {
      client.create().creatingParentsIfNeeded().forPath(drillUDFPath, udf_data);
      List<ACL> remoteACLs = client.getACL().forPath(drillUDFPath);
      List<ACL> desiredACLs = ((ZKACLProviderDelegate) aclProviderDelegate).aclProvider.getDrillAclForPath(drillUDFPath);
      Assert.assertEquals(remoteACLs.size(), desiredACLs.size());
      for (ACL remote : remoteACLs) {
        boolean found = false;
        for (ACL desired : desiredACLs) {
          // desiredACL list is READ_ACL_UNSAFE (READ, WORLD_ANYONE) + CREATOR_ALL_ACL(ALL, AUTH)
          // AUTH in CREATOR_ALL would translate to SASL, username. Hence the replacement
          // Note: The username("testuser1") should match the username in java.security.auth.login.config
          found = desired.toString().equals(remote.toString().replace("sasl", "auth").replace("testuser1", ""));
          if (found) { break; }
        }
        Assert.assertTrue(found);
      }
      // check if the data can be read
      byte[] actual = client.getData().forPath(drillUDFPath);
      Assert.assertArrayEquals("testNonClusterDiscoveryPaths data mismatch", udf_data, actual);

    } catch (Exception e) {
      throw new IllegalStateException("testNonClusterDiscoveryPaths failed");
    }
  }

  @After
  public void tearDown() throws Exception {
    client.close();
    server.close();
  }
}
