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

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.drill.common.exceptions.UserException;
import org.apache.drill.common.logical.StoragePluginConfig;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.store.dfs.FileSystemConfig;
import org.apache.drill.exec.store.dfs.FileSystemPlugin;
import org.apache.drill.exec.util.StoragePluginTestUtils;
import org.apache.drill.test.ClusterFixture;
import org.apache.drill.test.ClusterFixtureBuilder;
import org.junit.After;
import org.junit.Test;

/**
 * Tests the storage plugin registry. Plugins are (at present)
 * tightly coupled to the Drillbit context so we need to start
 * a Drillbit per tests to ensure each test works from a clean,
 * known registry.
 * <p>
 * This is several big tests because of the setup cost of
 * starting the Drillbits in the needed config.
 */
public class TestPluginRegistry extends BasePluginRegistryTest {

  @After
  public void cleanup() throws Exception {
    FileUtils.cleanDirectory(dirTestWatcher.getStoreDir());
  }

  @Test
  public void testBasicLifecycle() throws Exception {
    ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher);
    try (ClusterFixture cluster = builder.build();) {
      StoragePluginRegistry registry = cluster.storageRegistry();

      // Bootstrap file loaded.
      assertNotNull(registry.getPlugin(StoragePluginTestUtils.CP_PLUGIN_NAME)); // Normal
      assertNotNull(registry.getPlugin("sys")); // System
      assertNull(registry.getPlugin("bogus"));

      // Enabled plugins
      Map<String, StoragePluginConfig> configMap = registry.enabledConfigs();
      assertTrue(configMap.containsKey(StoragePluginTestUtils.CP_PLUGIN_NAME));
      assertFalse(configMap.containsKey("s3")); // Disabled, but still appears
      assertFalse(configMap.containsKey("sys"));

      // All stored plugins, including disabled
      configMap = registry.storedConfigs();
      assertTrue(configMap.containsKey(StoragePluginTestUtils.CP_PLUGIN_NAME));
      assertTrue(configMap.containsKey("s3")); // Disabled, but still appears
      assertFalse(configMap.containsKey("sys"));
      int bootstrapCount = configMap.size();

      // Create a new plugin
      FileSystemConfig pConfig1 = new FileSystemConfig("myConn",
          new HashMap<>(), new HashMap<>(), new HashMap<>());
      pConfig1.setEnabled(true);
      registry.put("myPlugin", pConfig1);
      StoragePlugin plugin1 = registry.getPlugin("myPlugin");
      assertNotNull(plugin1);
      assertSame(plugin1, registry.getPlugin(pConfig1));
      configMap = registry.storedConfigs();

      // Names converted to lowercase in persistent storage
      assertTrue(configMap.containsKey("myplugin"));
      assertEquals(bootstrapCount + 1, configMap.size());

      // Names are case-insensitive
      assertSame(plugin1, registry.getPlugin("myplugin"));
      assertSame(plugin1, registry.getPlugin("MYPLUGIN"));

      // Update the plugin
      Map<String, String> props = new HashMap<>();
      props.put("foo", "bar");
      FileSystemConfig pConfig2 = new FileSystemConfig("myConn",
          props, new HashMap<>(), new HashMap<>());
      pConfig2.setEnabled(true);
      registry.put("myPlugin", pConfig2);
      StoragePlugin plugin2 = registry.getPlugin("myPlugin");
      assertNotSame(plugin1, plugin2);
      assertTrue(plugin2 instanceof FileSystemPlugin);
      FileSystemPlugin fsStorage = (FileSystemPlugin) plugin2;
      assertSame(pConfig2, fsStorage.getConfig());
      assertSame(plugin2, registry.getPlugin(pConfig2));

      // Suppose a query was planned with plugin1 and now starts
      // to execute. Plugin1 has been replaced with plugin2. However
      // the registry moved the old plugin to ephemeral storage where
      // it can still be found by configuration.
      StoragePlugin ePlugin1 = registry.getPlugin(pConfig1);
      assertSame(plugin1, ePlugin1);
      assertNotSame(plugin2, ePlugin1);

      // Now, another thread does the same. It gets the same
      // ephemeral plugin.
      assertSame(plugin1, registry.getPlugin(pConfig1));

      // Change the stored plugin back to the first config.
      registry.put("myPlugin", pConfig1);

      // Now, lets suppose thread 3 starts to execute. It sees the original plugin
      assertSame(plugin1, registry.getPlugin("myPlugin"));

      // But, the ephemeral plugin lives on. Go back to the second
      // config.
      registry.put("myPlugin", pConfig2);
      assertSame(plugin2, registry.getPlugin("myPlugin"));

      // Thread 4, using the first config from planning in thread 3,
      // still sees the first plugin.
      assertSame(plugin1, registry.getPlugin(pConfig1));

      // Disable
      pConfig2.setEnabled(false);
      assertNull(registry.getPlugin("myPlugin"));

      // Though disabled, a running query will create an ephemeral
      // plugin for the config.
      assertSame(plugin2, registry.getPlugin(pConfig2));

      // Disabling an ephemeral plugin neither makes sense
      // nor will have any effect.
      ePlugin1.getConfig().setEnabled(false);
      assertSame(ePlugin1, registry.getPlugin(pConfig1));
      assertTrue(registry.storedConfigs().containsKey("myplugin"));
      assertFalse(registry.enabledConfigs().containsKey("myplugin"));

      // Enable. The config is retrieved from the persistent store.
      // We notice the config is in the ephemeral store and
      // so we restore it.
      pConfig2.setEnabled(true);
      assertSame(plugin2, registry.getPlugin("myPlugin"));
      assertSame(plugin2, registry.getPlugin(pConfig2));
      assertTrue(registry.storedConfigs().containsKey("myplugin"));
      assertTrue(registry.enabledConfigs().containsKey("myplugin"));

      // Delete the plugin
      registry.remove("myPlugin");
      assertNull(registry.getPlugin("myPlugin"));

      // Again a running query will retrieve the plugin from ephemeral storage
      assertSame(plugin1, registry.getPlugin(pConfig1));
      assertSame(plugin2, registry.getPlugin(pConfig2));

      // Delete again, no-op
      registry.remove("myPlugin");

      // The retrieve-from-ephemeral does not kick in if we create
      // a new plugin with the same config but a different name.
      pConfig1.setEnabled(true);
      registry.put("alias", pConfig1);
      StoragePlugin plugin4 = registry.getPlugin("alias");
      assertNotNull(plugin4);
      assertNotSame(plugin1, plugin4);

      // Delete the second name. The config is the same as one already
      // in ephemeral store, so the second is closed. The first will
      // be returned on subsequent queries.
      registry.remove("alias");
      assertNull(registry.getPlugin("alias"));
      assertSame(plugin1, registry.getPlugin(pConfig1));

      // Try to change a system plugin
      StoragePlugin sysPlugin = registry.getPlugin("sys");
      assertNotNull(sysPlugin);
      FileSystemConfig pConfig3 = new FileSystemConfig("myConn",
          props, new HashMap<>(), new HashMap<>());
      pConfig3.setEnabled(true);
      try {
        registry.put("sys", pConfig3);
        fail();
      } catch (UserException e) {
        // Expected
      }
      pConfig3.setEnabled(false);
      try {
        registry.put("sys", pConfig3);
        fail();
      } catch (UserException e) {
        // Expected
      }
      assertSame(sysPlugin, registry.getPlugin("sys"));

      // Try to delete a system plugin
      try {
        registry.remove("sys");
        fail();
      } catch (UserException e) {
        // Expected
      }

      // There is no protection for disabling a system plugin because
      // there is no code that will allow that at present.
    }
  }

  @Test
  public void testStoreSync() throws Exception {
    ClusterFixtureBuilder builder = ClusterFixture.builder(dirTestWatcher)
        .withBits("bit1", "bit2");

    // We want a non-buffered, local file system store, in a known location
    // so that the two Drillbits will coordinate roughly he same way they
    // will when using the ZK store in distributed mode.
    builder.configBuilder()
      .put(ExecConstants.SYS_STORE_PROVIDER_LOCAL_ENABLE_WRITE, true)
      .put(ExecConstants.SYS_STORE_PROVIDER_LOCAL_PATH,
          dirTestWatcher.getStoreDir().getAbsolutePath());
    try (ClusterFixture cluster = builder.build();) {
      StoragePluginRegistry registry1 = cluster.storageRegistry("bit1");
      StoragePluginRegistry registry2 = cluster.storageRegistry("bit2");

      // Define a plugin in Drillbit 1
      FileSystemConfig pConfig1 = new FileSystemConfig("myConn",
          new HashMap<>(), new HashMap<>(), new HashMap<>());
      pConfig1.setEnabled(true);
      registry1.put("myPlugin", pConfig1);
      StoragePlugin plugin1 = registry1.getPlugin("myPlugin");
      assertNotNull(plugin1);

      // Should appear in Drillbit 2
      StoragePlugin plugin2 = registry2.getPlugin("myPlugin");
      assertNotNull(plugin2);
      assertEquals(pConfig1, plugin1.getConfig());

      // Change in Drillbit 1
      Map<String, String> props = new HashMap<>();
      props.put("foo", "bar");
      FileSystemConfig pConfig3 = new FileSystemConfig("myConn",
          props, new HashMap<>(), new HashMap<>());
      pConfig3.setEnabled(true);
      registry1.put("myPlugin", pConfig3);
      plugin1 = registry1.getPlugin("myPlugin");
      assertSame(pConfig3, plugin1.getConfig());

      // Change should appear in Drillbit 2
      plugin2 = registry2.getPlugin("myPlugin");
      assertNotNull(plugin2);
      assertEquals(pConfig3, plugin1.getConfig());

      // Delete in Drillbit 2
      registry2.remove("myPlugin");

      // Should not be available in Drillbit 1
      assertNull(registry1.getPlugin("myPlugin"));
    }
  }
}
