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

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import com.google.common.collect.ImmutableMap;
import org.apache.commons.io.FileUtils;
import org.apache.jute.InputArchive;
import org.apache.jute.OutputArchive;
import org.apache.jute.Record;
import org.apache.solr.SolrTestCaseJ4;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.impl.HttpSolrClient.RemoteSolrException;
import org.apache.solr.client.solrj.request.ConfigSetAdminRequest.Create;
import org.apache.solr.common.SolrException;
import org.apache.solr.common.cloud.SolrZkClient;
import org.apache.solr.common.cloud.ZkConfigManager;
import org.apache.solr.common.util.Utils;
import org.apache.solr.core.ConfigSetProperties;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.KeeperException.NoNodeException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.server.DataNode;
import org.apache.zookeeper.server.DataTree;
import org.apache.zookeeper.server.DataTree.ProcessTxnResult;
import org.apache.zookeeper.server.Request;
import org.apache.zookeeper.server.ServerCnxn;
import org.apache.zookeeper.server.ZKDatabase;
import org.apache.zookeeper.server.quorum.Leader.Proposal;
import org.apache.zookeeper.txn.TxnDigest;
import org.apache.zookeeper.txn.TxnHeader;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import static org.apache.solr.common.cloud.ZkConfigManager.CONFIGS_ZKNODE;

/**
 * Test the ConfigSets API under ZK failure.  In particular,
 * if create fails, ensure proper cleanup occurs so we aren't
 * left with a partially created ConfigSet.
 */
public class TestConfigSetsAPIZkFailure extends SolrTestCaseJ4 {
  private MiniSolrCloudCluster solrCluster;
  private ZkTestServer zkTestServer;
  private static final String BASE_CONFIGSET_NAME = "baseConfigSet1";
  private static final String CONFIGSET_NAME = "configSet1";

  @Override
  @Before
  public void setUp() throws Exception {
    super.setUp();
    final Path testDir = createTempDir();
    final Path zkDir = testDir.resolve("zookeeper/server1/data");
    zkTestServer = new ZkTestServer(zkDir);
    zkTestServer.run();
    zkTestServer.setZKDatabase(new FailureDuringCopyZKDatabase(zkTestServer.getZKDatabase(), zkTestServer));
    solrCluster = new MiniSolrCloudCluster(1, testDir,
        MiniSolrCloudCluster.DEFAULT_CLOUD_SOLR_XML, buildJettyConfig("/solr"), zkTestServer);
  }

  @Override
  @After
  public void tearDown() throws Exception {
    if (null != solrCluster) {
      solrCluster.shutdown();
      solrCluster = null;
    }
    if (null != zkTestServer) {
      zkTestServer.shutdown();
      zkTestServer = null;
    }
    super.tearDown();
  }

  @Test
  public void testCreateZkFailure() throws Exception {
    final String baseUrl = solrCluster.getJettySolrRunners().get(0).getBaseUrl().toString();
    final SolrClient solrClient = getHttpSolrClient(baseUrl);

    final Map<String, String> oldProps = ImmutableMap.of("immutable", "true");
    setupBaseConfigSet(BASE_CONFIGSET_NAME, oldProps);

    SolrZkClient zkClient = new SolrZkClient(solrCluster.getZkServer().getZkAddress(),
        AbstractZkTestCase.TIMEOUT, AbstractZkTestCase.TIMEOUT, null);
    try {
      ZkConfigManager configManager = new ZkConfigManager(zkClient);
      assertFalse(configManager.configExists(CONFIGSET_NAME));

      Create create = new Create();
      create.setBaseConfigSetName(BASE_CONFIGSET_NAME).setConfigSetName(CONFIGSET_NAME);
      RemoteSolrException se = expectThrows(RemoteSolrException.class, () -> create.process(solrClient));
      // partial creation should have been cleaned up
      assertFalse(configManager.configExists(CONFIGSET_NAME));
      assertEquals(SolrException.ErrorCode.SERVER_ERROR.code, se.code());
    } finally {
      zkClient.close();
    }

    solrClient.close();
  }

  private void setupBaseConfigSet(String baseConfigSetName, Map<String, String> oldProps) throws Exception {
    final File configDir = getFile("solr").toPath().resolve("configsets/configset-2/conf").toFile();
    final File tmpConfigDir = createTempDir().toFile();
    tmpConfigDir.deleteOnExit();
    FileUtils.copyDirectory(configDir, tmpConfigDir);
    if (oldProps != null) {
      FileUtils.write(new File(tmpConfigDir, ConfigSetProperties.DEFAULT_FILENAME),
          getConfigSetProps(oldProps), StandardCharsets.UTF_8);
    }
    solrCluster.uploadConfigSet(tmpConfigDir.toPath(), baseConfigSetName);
    solrCluster.getZkClient().setData("/configs/" + baseConfigSetName, "{\"trusted\": false}".getBytes(StandardCharsets.UTF_8), true);
  }

  private StringBuilder getConfigSetProps(Map<String, String> map) {
    return new StringBuilder(new String(Utils.toJSON(map), StandardCharsets.UTF_8));
  }

  private static class FailureDuringCopyZKDatabase extends ForwardingZKDatabase {
    private final ZkTestServer zkTestServer;

    public FailureDuringCopyZKDatabase(ZKDatabase zkdb, ZkTestServer zkTestServer) {
      super(zkdb);
      this.zkTestServer = zkTestServer;
    }

    @Override
    public byte[] getData(String path, Stat stat, Watcher watcher) throws KeeperException.NoNodeException {
      // we know we are doing a copy when we are getting data from the base config set and
      // the new config set (partially) exists
      String zkAddress = zkTestServer.getZkAddress();
      String chroot = zkAddress.substring(zkAddress.lastIndexOf("/"));
      if (path.startsWith(chroot + CONFIGS_ZKNODE + "/" + BASE_CONFIGSET_NAME)
          && !path.contains(ConfigSetProperties.DEFAULT_FILENAME)) {
        List<String> children = null;
        try {
          children = getChildren(chroot + CONFIGS_ZKNODE + "/" + CONFIGSET_NAME, null, null);
        } catch (KeeperException.NoNodeException e) {}
        if (children != null && children.size() > 0) {
          throw new RuntimeException("sample zookeeper error");
        }
      }
      return super.getData(path, stat, watcher);
    }
  }

  private static class ForwardingZKDatabase extends ZKDatabase {
    private ZKDatabase zkdb;

    public ForwardingZKDatabase(ZKDatabase zkdb) {
      super(null);
      this.zkdb = zkdb;
    }

    @Override
    public boolean isInitialized() {
      return zkdb.isInitialized();
    }

    @Override
    public void clear() {
      zkdb.clear();
    }

    @Override
    public DataTree getDataTree() {
      return zkdb.getDataTree();
    }

    @Override
    public long getmaxCommittedLog() {
      return zkdb.getmaxCommittedLog();
    }

    @Override
    public long getminCommittedLog() {
      return zkdb.getminCommittedLog();
    }

    @Override
    public ReentrantReadWriteLock getLogLock() {
      return zkdb.getLogLock();
    }

    @Override
    public synchronized Collection<Proposal> getCommittedLog() {
      return zkdb.getCommittedLog();
    }

    @Override
    public long getDataTreeLastProcessedZxid() {
      return zkdb.getDataTreeLastProcessedZxid();
    }

    @Override
    public Collection<Long> getSessions() {
      return zkdb.getSessions();
    }

    @Override
    public ConcurrentHashMap<Long, Integer> getSessionWithTimeOuts() {
      return zkdb.getSessionWithTimeOuts();
    }

    @Override
    public long loadDataBase() throws IOException {
      return zkdb.loadDataBase();
    }

    @Override
    public void addCommittedProposal(Request request) {
      zkdb.addCommittedProposal(request);
    }

    @Override
    public void removeCnxn(ServerCnxn cnxn) {
      zkdb.removeCnxn(cnxn);
    }

    @Override
    public void killSession(long sessionId, long zxid) {
      zkdb.killSession(sessionId, zxid);
    }

    @Override
    public void dumpEphemerals(PrintWriter pwriter) {
      zkdb.dumpEphemerals(pwriter);
    }

    @Override
    public int getNodeCount() {
      return zkdb.getNodeCount();
    }

    @Override
    public Set<String> getEphemerals(long sessionId) {
      return zkdb.getEphemerals(sessionId);
    }

    @Override
    public void setlastProcessedZxid(long zxid) {
      zkdb.setlastProcessedZxid(zxid);
    }

    @Override
    public ProcessTxnResult processTxn(TxnHeader hdr, Record txn, TxnDigest digest) {
      return zkdb.processTxn(hdr, txn, digest);
    }

    @Override
    public Stat statNode(String path, ServerCnxn serverCnxn) throws KeeperException.NoNodeException {
      return zkdb.statNode(path, serverCnxn);
    }

    @Override
    public DataNode getNode(String path) {
      return zkdb.getNode(path);
    }

    @Override
    public List<ACL> aclForNode(DataNode n) {
      return zkdb.aclForNode(n);
    }

    @Override
    public byte[] getData(String path, Stat stat, Watcher watcher)
    throws KeeperException.NoNodeException {
      return zkdb.getData(path, stat, watcher);
    }

    @Override
    public void setWatches(long relativeZxid, List<String> dataWatches,
                           List<String> existWatches, List<String> childWatches,
                           List<String> persistentWatches,
                           List<String> persistentRecursiveWatches,
                           Watcher watcher) {
      zkdb.setWatches(relativeZxid, dataWatches, existWatches, childWatches,
              persistentWatches, persistentRecursiveWatches, watcher);

      }

    @Override
    public List<ACL> getACL(String path, Stat stat) throws NoNodeException {
      return zkdb.getACL(path, stat);
    }

    @Override
    public List<String> getChildren(String path, Stat stat, Watcher watcher)
    throws KeeperException.NoNodeException {
      return zkdb.getChildren(path, stat, watcher);
    }

    @Override
    public boolean isSpecialPath(String path) {
      return zkdb.isSpecialPath(path);
    }

    @Override
    public int getAclSize() {
      return zkdb.getAclSize();
    }

    @Override
    public boolean truncateLog(long zxid) throws IOException {
      return zkdb.truncateLog(zxid);
    }

    @Override
    public void deserializeSnapshot(InputArchive ia) throws IOException {
      zkdb.deserializeSnapshot(ia);
    }

    @Override
    public void serializeSnapshot(OutputArchive oa) throws IOException,
    InterruptedException {
      zkdb.serializeSnapshot(oa);
    }

    @Override
    public boolean append(Request si) throws IOException {
      return zkdb.append(si);
    }

    @Override
    public void rollLog() throws IOException {
      zkdb.rollLog();
    }

    @Override
    public void commit() throws IOException {
      zkdb.commit();
    }

    @Override
    public void close() throws IOException {
      zkdb.close();
    }
    @Override
    public int getTxnCount() {
      return zkdb.getTxnCount();
    }

    @Override
    public long getTxnSize() {
      return zkdb.getTxnSize();
    }

  }
}
