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

import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.Phaser;
import java.util.concurrent.TimeUnit;

import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.IOUtils;
import org.apache.lucene.util.ResourceLoader;
import org.apache.lucene.util.ResourceLoaderAware;
import org.apache.solr.api.Command;
import org.apache.solr.api.ConfigurablePlugin;
import org.apache.solr.api.ContainerPluginsRegistry;
import org.apache.solr.api.EndPoint;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.embedded.JettySolrRunner;
import org.apache.solr.client.solrj.impl.BaseHttpSolrClient.RemoteExecutionException;
import org.apache.solr.client.solrj.request.V2Request;
import org.apache.solr.client.solrj.request.beans.Package;
import org.apache.solr.client.solrj.request.beans.PluginMeta;
import org.apache.solr.client.solrj.response.V2Response;
import org.apache.solr.cloud.ClusterSingleton;
import org.apache.solr.cloud.MiniSolrCloudCluster;
import org.apache.solr.cloud.SolrCloudTestCase;
import org.apache.solr.common.NavigableObject;
import org.apache.solr.common.annotation.JsonProperty;
import org.apache.solr.common.util.ReflectMapWriter;
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.CoreContainer;
import org.apache.solr.core.SolrResourceLoader;
import org.apache.solr.filestore.PackageStoreAPI;
import org.apache.solr.filestore.TestDistribPackageStore;
import org.apache.solr.filestore.TestDistribPackageStore.Fetcher;
import org.apache.solr.pkg.TestPackages;
import org.apache.solr.request.SolrQueryRequest;
import org.apache.solr.response.SolrQueryResponse;
import org.apache.solr.security.PermissionNameProvider;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static java.util.Collections.singletonList;
import static java.util.Collections.singletonMap;
import static org.apache.solr.client.solrj.SolrRequest.METHOD.GET;
import static org.apache.solr.filestore.TestDistribPackageStore.readFile;
import static org.apache.solr.filestore.TestDistribPackageStore.uploadKey;

public class TestContainerPlugin extends SolrCloudTestCase {
  private Phaser phaser;

  @Before
  public void setup() {
    System.setProperty("enable.packages", "true");
    phaser = new Phaser();
  }

  @After
  public void teardown() {
    System.clearProperty("enable.packages");
  }

  @Test
  public void testApi() throws Exception {
    MiniSolrCloudCluster cluster =
            configureCluster(4)
                    .withJettyConfig(jetty -> jetty.enableV2(true))
                    .configure();
    ContainerPluginsRegistry pluginsRegistry = cluster.getOpenOverseer().getCoreContainer().getContainerPluginsRegistry();
    pluginsRegistry.setPhaser(phaser);

    int version = phaser.getPhase();

    String errPath = "/error/details[0]/errorMessages[0]";
    try {
      PluginMeta plugin = new PluginMeta();
      plugin.name = "testplugin";
      plugin.klass = C2.class.getName();
      //test with an invalid class
      V2Request req = new V2Request.Builder("/cluster/plugin")
              .forceV2(true)
              .POST()
              .withPayload(singletonMap("add", plugin))
              .build();
      expectError(req, cluster.getSolrClient(), errPath, "No method with @Command in class");

      //test with a valid class. This should succeed now
      plugin.klass = C3.class.getName();
      req.process(cluster.getSolrClient());

      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);

      //just check if the plugin is indeed registered
      V2Request readPluginState = new V2Request.Builder("/cluster/plugin")
              .forceV2(true)
              .GET()
              .build();
      V2Response rsp = readPluginState.process(cluster.getSolrClient());
      assertEquals(C3.class.getName(), rsp._getStr("/plugin/testplugin/class", null));

      //let's test the plugin
      TestDistribPackageStore.assertResponseValues(10,
              () -> new V2Request.Builder("/plugin/my/plugin")
                      .forceV2(true)
                      .GET()
                      .build().process(cluster.getSolrClient()),
              ImmutableMap.of("/testkey", "testval"));

      //now remove the plugin
      new V2Request.Builder("/cluster/plugin")
              .POST()
              .forceV2(true)
              .withPayload("{remove : testplugin}")
              .build()
              .process(cluster.getSolrClient());

      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);

      //verify it is removed
      rsp = readPluginState.process(cluster.getSolrClient());
      assertEquals(null, rsp._get("/plugin/testplugin/class", null));

      //test with a class  @EndPoint methods. This also uses a template in the path name
      plugin.klass = C4.class.getName();
      plugin.name = "collections";
      plugin.pathPrefix = "collections";
      expectError(req, cluster.getSolrClient(), errPath, "path must not have a prefix: collections");

      plugin.name = "my-random-name";
      plugin.pathPrefix = "my-random-prefix";

      req.process(cluster.getSolrClient());
      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);

      //let's test the plugin
      TestDistribPackageStore.assertResponseValues(10,
              () -> new V2Request.Builder("/my-random-name/my/plugin")
                      .forceV2(true)
                      .GET()
                      .build().process(cluster.getSolrClient()),
              ImmutableMap.of("/method.name", "m1"));

      TestDistribPackageStore.assertResponseValues(10,
              () -> new V2Request.Builder("/my-random-prefix/their/plugin")
                      .forceV2(true)
                      .GET()
                      .build().process(cluster.getSolrClient()),
              ImmutableMap.of("/method.name", "m2"));
      //now remove the plugin
      new V2Request.Builder("/cluster/plugin")
              .POST()
              .forceV2(true)
              .withPayload("{remove : my-random-name}")
              .build()
              .process(cluster.getSolrClient());

      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);

      expectFail(() -> new V2Request.Builder("/my-random-prefix/their/plugin")
              .forceV2(true)
              .GET()
              .build()
              .process(cluster.getSolrClient()));
      expectFail(() -> new V2Request.Builder("/my-random-prefix/their/plugin")
              .forceV2(true)
              .GET()
              .build()
              .process(cluster.getSolrClient()));

      // test ClusterSingleton plugin
      plugin.name = "clusterSingleton";
      plugin.klass = C6.class.getName();
      req.process(cluster.getSolrClient());
      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);


        //just check if the plugin is indeed registered
      readPluginState = new V2Request.Builder("/cluster/plugin")
              .forceV2(true)
              .GET()
              .build();
      rsp = readPluginState.process(cluster.getSolrClient());
      assertEquals(C6.class.getName(), rsp._getStr("/plugin/clusterSingleton/class", null));

      assertTrue("ccProvided", C6.ccProvided);
      assertTrue("startCalled", C6.startCalled);
      assertFalse("stopCalled", C6.stopCalled);

      assertEquals(CConfig.class, ContainerPluginsRegistry.getConfigClass(new CC()));
      assertEquals(CConfig.class, ContainerPluginsRegistry.getConfigClass(new CC1()));
      assertEquals(CConfig.class, ContainerPluginsRegistry.getConfigClass(new CC2()));

      CConfig cfg = new CConfig();
      cfg.boolVal = Boolean.TRUE;
      cfg.strVal = "Something";
      cfg.longVal = 1234L;
      PluginMeta p = new PluginMeta();
      p.name = "hello";
      p.klass = CC.class.getName();
      p.config = cfg;

      new V2Request.Builder("/cluster/plugin")
              .forceV2(true)
              .POST()
              .withPayload(singletonMap("add", p))
              .build()
              .process(cluster.getSolrClient());

      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);

        TestDistribPackageStore.assertResponseValues(10,
              () -> new V2Request.Builder("hello/plugin")
                      .forceV2(true)
                      .GET()
                      .build().process(cluster.getSolrClient()),
              ImmutableMap.of("/config/boolVal", "true", "/config/strVal", "Something", "/config/longVal", "1234"));

      cfg.strVal = "Something else";
      new V2Request.Builder("/cluster/plugin")
              .forceV2(true)
              .POST()
              .withPayload(singletonMap("update", p))
              .build()
              .process(cluster.getSolrClient());
      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);

      TestDistribPackageStore.assertResponseValues(10,
              () -> new V2Request.Builder("hello/plugin")
                      .forceV2(true)
                      .GET()
                      .build().process(cluster.getSolrClient()),
              ImmutableMap.of("/config/boolVal", "true", "/config/strVal", cfg.strVal, "/config/longVal", "1234"));

      // kill the Overseer leader
      for (JettySolrRunner jetty : cluster.getJettySolrRunners()) {
        if (!jetty.getCoreContainer().getZkController().getOverseer().isClosed()) {
          cluster.stopJettySolrRunner(jetty);
          cluster.waitForJettyToStop(jetty);
        }
      }
      assertTrue("stopCalled", C6.stopCalled);
    } finally {
      cluster.shutdown();
    }
  }

  private void expectFail(ThrowingRunnable runnable) throws Exception {
    for (int i = 0; i < 20; i++) {
      try {
        runnable.run();
      } catch (Throwable throwable) {
        return;
      }
      Thread.sleep(100);
    }
    fail("should have failed with an exception");
  }

  @Test
  public void testApiFromPackage() throws Exception {
    MiniSolrCloudCluster cluster =
            configureCluster(4)
                    .withJettyConfig(jetty -> jetty.enableV2(true))
                    .configure();
    String FILE1 = "/myplugin/v1.jar";
    String FILE2 = "/myplugin/v2.jar";
    ContainerPluginsRegistry pluginsRegistry = cluster.getOpenOverseer().getCoreContainer().getContainerPluginsRegistry();
    pluginsRegistry.setPhaser(phaser);

    int version = phaser.getPhase();


    String errPath = "/error/details[0]/errorMessages[0]";
    try {
      byte[] derFile = readFile("cryptokeys/pub_key512.der");
      uploadKey(derFile, PackageStoreAPI.KEYS_DIR + "/pub_key512.der", cluster);
      TestPackages.postFileAndWait(cluster, "runtimecode/containerplugin.v.1.jar.bin", FILE1,
              "pmrmWCDafdNpYle2rueAGnU2J6NYlcAey9mkZYbqh+5RdYo2Ln+llLF9voyRj+DDivK9GV1XdtKvD9rgCxlD7Q==");
      TestPackages.postFileAndWait(cluster, "runtimecode/containerplugin.v.2.jar.bin", FILE2,
              "StR3DmqaUSL7qjDOeVEiCqE+ouiZAkW99fsL48F9oWG047o7NGgwwZ36iGgzDC3S2tPaFjRAd9Zg4UK7OZLQzg==");

      // We have two versions of the plugin in 2 different jar files. they are already uploaded to the package store
      Package.AddVersion add = new Package.AddVersion();
      add.version = "1.0";
      add.pkg = "mypkg";
      add.files = singletonList(FILE1);
      V2Request addPkgVersionReq = new V2Request.Builder("/cluster/package")
              .forceV2(true)
              .POST()
              .withPayload(singletonMap("add", add))
              .build();
      addPkgVersionReq.process(cluster.getSolrClient());

      waitForAllNodesToSync(cluster, "/cluster/package", Utils.makeMap(
              ":result:packages:mypkg[0]:version", "1.0",
              ":result:packages:mypkg[0]:files[0]", FILE1
      ));

      // Now lets create a plugin using v1 jar file
      PluginMeta plugin = new PluginMeta();
      plugin.name = "myplugin";
      plugin.klass = "mypkg:org.apache.solr.handler.MyPlugin";
      plugin.version = add.version;
      final V2Request req1 = new V2Request.Builder("/cluster/plugin")
              .forceV2(true)
              .POST()
              .withPayload(singletonMap("add", plugin))
              .build();
      req1.process(cluster.getSolrClient());
      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);

        //verify the plugin creation
      TestDistribPackageStore.assertResponseValues(10,
              () -> new V2Request.Builder("/cluster/plugin").
                      GET()
                      .build().process(cluster.getSolrClient()),
              ImmutableMap.of(
                      "/plugin/myplugin/class", plugin.klass,
                      "/plugin/myplugin/version", plugin.version
              ));
      //let's test this now
      Callable<NavigableObject> invokePlugin = () -> new V2Request.Builder("/plugin/my/path")
              .forceV2(true)
              .GET()
              .build().process(cluster.getSolrClient());
      TestDistribPackageStore.assertResponseValues(10,
              invokePlugin,
              ImmutableMap.of("/myplugin.version", "1.0"));

      //now let's upload the jar file for version 2.0 of the plugin
      add.version = "2.0";
      add.files = singletonList(FILE2);
      addPkgVersionReq.process(cluster.getSolrClient());

      //here the plugin version is updated
      plugin.version = add.version;
      new V2Request.Builder("/cluster/plugin")
              .forceV2(true)
              .POST()
              .withPayload(singletonMap("update", plugin))
              .build()
              .process(cluster.getSolrClient());
      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);

      //now verify if it is indeed updated
      TestDistribPackageStore.assertResponseValues(10,
              () -> new V2Request.Builder("/cluster/plugin").
                      GET()
                      .build().process(cluster.getSolrClient()),
              ImmutableMap.of(
                      "/plugin/myplugin/class", plugin.klass,
                      "/plugin/myplugin/version", "2.0"
              ));
      // invoke the plugin and test thye output
      TestDistribPackageStore.assertResponseValues(10,
              invokePlugin,
              ImmutableMap.of("/myplugin.version", "2.0"));

      plugin.name = "plugin2";
      plugin.klass = "mypkg:" + C5.class.getName();
      plugin.version = "2.0";
      req1.process(cluster.getSolrClient());
      version = phaser.awaitAdvanceInterruptibly(version, 10, TimeUnit.SECONDS);
      assertNotNull(C5.classData);
      assertEquals(1452, C5.classData.limit());
    } finally {
      cluster.shutdown();
    }
  }

  public static class CC1 extends CC {

  }

  public static class CC2 extends CC1 {

  }

  public static class CC implements ConfigurablePlugin<CConfig> {
    private CConfig cfg;


    @Override
    public void configure(CConfig cfg) {
      this.cfg = cfg;

    }

    @EndPoint(method = GET,
            path = "/hello/plugin",
            permission = PermissionNameProvider.Name.READ_PERM)
    public void m2(SolrQueryRequest req, SolrQueryResponse rsp) {
      rsp.add("config", cfg);
    }

  }

  public static class CConfig implements ReflectMapWriter {

    @JsonProperty
    public String strVal;

    @JsonProperty
    public Long longVal;

    @JsonProperty
    public Boolean boolVal;
  }

  public static class C6 implements ClusterSingleton {
    static boolean startCalled = false;
    static boolean stopCalled = false;
    static boolean ccProvided = false;

    private State state = State.STOPPED;

    public C6(CoreContainer cc) {
      if (cc != null) {
        ccProvided = true;
      }
    }

    @Override
    public String getName() {
      return "C6";
    }

    @Override
    public void start() throws Exception {
      state = State.STARTING;
      startCalled = true;
      state = State.RUNNING;
    }

    @Override
    public State getState() {
      return state;
    }

    @Override
    public void stop() {
      state = State.STOPPING;
      stopCalled = true;
      state = State.STOPPED;
    }
  }


  public static class C5 implements ResourceLoaderAware {
    static ByteBuffer classData;
    private SolrResourceLoader resourceLoader;

    @Override
    public void inform(ResourceLoader loader) throws IOException {
      this.resourceLoader = (SolrResourceLoader) loader;
      try {
        InputStream is = resourceLoader.openResource("org/apache/solr/handler/MyPlugin.class");
        byte[] buf = new byte[1024 * 5];
        int sz = IOUtils.read(is, buf);
        classData = ByteBuffer.wrap(buf, 0, sz);
      } catch (IOException e) {
        //do not do anything
      }
    }

    @EndPoint(method = GET,
            path = "/$plugin-name/m2",
            permission = PermissionNameProvider.Name.COLL_READ_PERM)
    public void m2() {


    }

  }

  public static class C1 {

  }

  @EndPoint(
          method = GET,
          path = "/plugin/my/plugin",
          permission = PermissionNameProvider.Name.COLL_READ_PERM)
  public class C2 {


  }

  @EndPoint(
          method = GET,
          path = "/plugin/my/plugin",
          permission = PermissionNameProvider.Name.COLL_READ_PERM)
  public static class C3 {
    @Command
    public void read(SolrQueryRequest req, SolrQueryResponse rsp) {
      rsp.add("testkey", "testval");
    }

  }

  public static class C4 {

    @EndPoint(method = GET,
            path = "$plugin-name/my/plugin",
            permission = PermissionNameProvider.Name.READ_PERM)
    public void m1(SolrQueryRequest req, SolrQueryResponse rsp) {
      rsp.add("method.name", "m1");
    }

    @EndPoint(method = GET,
            path = "$path-prefix/their/plugin",
            permission = PermissionNameProvider.Name.READ_PERM)
    public void m2(SolrQueryRequest req, SolrQueryResponse rsp) {
      rsp.add("method.name", "m2");
    }

  }

  @SuppressWarnings("unchecked")
  public static void waitForAllNodesToSync(MiniSolrCloudCluster cluster, String path, Map<String, Object> expected) throws Exception {
    for (JettySolrRunner jettySolrRunner : cluster.getJettySolrRunners()) {
      String baseUrl = jettySolrRunner.getBaseUrl().toString().replace("/solr", "/api");
      String url = baseUrl + path + "?wt=javabin";
      TestDistribPackageStore.assertResponseValues(10, new Fetcher(url, jettySolrRunner), expected);
    }
  }

  private void expectError(V2Request req, SolrClient client, String errPath, String expectErrorMsg) throws IOException, SolrServerException {
    RemoteExecutionException e = expectThrows(RemoteExecutionException.class, () -> req.process(client));
    String msg = e.getMetaData()._getStr(errPath, "");
    assertTrue(expectErrorMsg, msg.contains(expectErrorMsg));
  }
}
