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

import java.io.Closeable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import org.apache.curator.CuratorZookeeperClient;
import org.apache.curator.framework.api.*;
import org.apache.curator.framework.api.transaction.CuratorMultiTransaction;
import org.apache.curator.framework.api.transaction.CuratorOp;
import org.apache.curator.framework.api.transaction.CuratorTransaction;
import org.apache.curator.framework.api.transaction.TransactionOp;
import org.apache.curator.framework.imps.CuratorFrameworkState;
import org.apache.curator.framework.listen.Listenable;
import org.apache.curator.framework.schema.SchemaSet;
import org.apache.curator.framework.state.ConnectionStateErrorPolicy;
import org.apache.curator.framework.state.ConnectionStateListener;
import org.apache.curator.utils.EnsurePath;
import org.apache.curator.utils.ZookeeperCompatibility;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier;

/**
 * Zookeeper framework-style client
 */
public interface CuratorFramework extends Closeable {
    /**
     * Start the client. Most mutator methods will not work until the client is started
     */
    public void start();

    /**
     * Stop the client
     */
    public void close();

    /**
     * Returns the state of this instance
     *
     * @return state
     */
    public CuratorFrameworkState getState();

    /**
     * Return true if the client is started, not closed, etc.
     *
     * @return true/false
     * @deprecated use {@link #getState()} instead
     */
    @Deprecated
    public boolean isStarted();

    /**
     * Start a create builder
     *
     * @return builder object
     */
    public CreateBuilder create();

    /**
     * Start a delete builder
     *
     * @return builder object
     */
    public DeleteBuilder delete();

    /**
     * Start an exists builder
     * <p>
     * The builder will return a Stat object as if org.apache.zookeeper.ZooKeeper.exists() were called.  Thus, a null
     * means that it does not exist and an actual Stat object means it does exist.
     *
     * @return builder object
     */
    public ExistsBuilder checkExists();

    /**
     * Start a get data builder
     *
     * @return builder object
     */
    public GetDataBuilder getData();

    /**
     * Start a set data builder
     *
     * @return builder object
     */
    public SetDataBuilder setData();

    /**
     * Start a get children builder
     *
     * @return builder object
     */
    public GetChildrenBuilder getChildren();

    /**
     * Start a get ACL builder
     *
     * @return builder object
     */
    public GetACLBuilder getACL();

    /**
     * Start a set ACL builder
     *
     * @return builder object
     */
    public SetACLBuilder setACL();

    /**
     * Start a reconfig builder
     *
     * @return builder object
     */
    public ReconfigBuilder reconfig();

    /**
     * Start a getConfig builder
     *
     * @return builder object
     */
    public GetConfigBuilder getConfig();

    /**
     * Start a transaction builder
     *
     * @return builder object
     * @deprecated use {@link #transaction()} instead
     */
    public CuratorTransaction inTransaction();

    /**
     * Start a transaction builder
     *
     * @return builder object
     */
    public CuratorMultiTransaction transaction();

    /**
     * Allocate an operation that can be used with {@link #transaction()}.
     * NOTE: {@link CuratorOp} instances created by this builder are
     * reusable.
     *
     * @return operation builder
     */
    public TransactionOp transactionOp();

    /**
     * Perform a sync on the given path - syncs are always in the background
     *
     * @param path                    the path
     * @param backgroundContextObject optional context
     * @deprecated use {@link #sync()} instead
     */
    @Deprecated
    public void sync(String path, Object backgroundContextObject);

    /**
     * Create all nodes in the specified path as containers if they don't
     * already exist
     *
     * @param path path to create
     * @throws Exception errors
     */
    public void createContainers(String path) throws Exception;

    /**
     * Start a sync builder. Note: sync is ALWAYS in the background even
     * if you don't use one of the background() methods
     *
     * @return builder object
     */
    public SyncBuilder sync();

    /**
     * Start a remove watches builder.
     *
     * @return builder object
     * @deprecated use {@link #watchers()} in ZooKeeper 3.6+
     */
    public RemoveWatchesBuilder watches();

    /**
     * Start a watch builder. Supported only when ZooKeeper JAR of version 3.6 or
     * above is used, throws {@code IllegalStateException} for ZooKeeper JAR 3.5 or below
     *
     * @return builder object
     * @throws IllegalStateException ZooKeeper JAR is 3.5 or below
     */
    public WatchesBuilder watchers();

    /**
     * Returns the listenable interface for the Connect State
     *
     * @return listenable
     */
    public Listenable<ConnectionStateListener> getConnectionStateListenable();

    /**
     * Returns the listenable interface for events
     *
     * @return listenable
     */
    public Listenable<CuratorListener> getCuratorListenable();

    /**
     * Returns the listenable interface for unhandled errors
     *
     * @return listenable
     */
    public Listenable<UnhandledErrorListener> getUnhandledErrorListenable();

    /**
     * Returns a facade of the current instance that does _not_ automatically
     * pre-pend the namespace to all paths
     *
     * @return facade
     * @deprecated Since 2.9.0 - use {@link #usingNamespace} passing <code>null</code>
     */
    @Deprecated
    public CuratorFramework nonNamespaceView();

    /**
     * Returns a facade of the current instance that uses the specified namespace
     * or no namespace if <code>newNamespace</code> is <code>null</code>.
     *
     * @param newNamespace the new namespace or null for none
     * @return facade
     */
    public CuratorFramework usingNamespace(String newNamespace);

    /**
     * Return the current namespace or "" if none
     *
     * @return namespace
     */
    public String getNamespace();

    /**
     * Return the managed zookeeper client
     *
     * @return client
     */
    public CuratorZookeeperClient getZookeeperClient();

    /**
     * Return zookeeper server compatibility
     *
     * @return compatibility
     */
    public ZookeeperCompatibility getZookeeperCompatibility();

    /**
     * Allocates an ensure path instance that is namespace aware
     *
     * @param path path to ensure
     * @return new EnsurePath instance
     * @deprecated Since 2.9.0 - prefer {@link CreateBuilder#creatingParentContainersIfNeeded()}, {@link ExistsBuilder#creatingParentContainersIfNeeded()}
     * or {@link CuratorFramework#createContainers(String)}
     */
    @Deprecated
    public EnsurePath newNamespaceAwareEnsurePath(String path);

    /**
     * Curator can hold internal references to watchers that may inhibit garbage collection.
     * Call this method on watchers you are no longer interested in.
     *
     * @param watcher the watcher
     *
     * @deprecated As of ZooKeeper 3.5 Curators recipes will handle removing watcher references
     * when they are no longer used. If you write your own recipe, follow the example of Curator
     * recipes and use {@link #newWatcherRemoveCuratorFramework} calling {@link WatcherRemoveCuratorFramework#removeWatchers()}
     * when closing your instance.
     */
    @Deprecated
    public void clearWatcherReferences(Watcher watcher);

    /**
     * Block until a connection to ZooKeeper is available or the maxWaitTime has been exceeded
     * @param maxWaitTime The maximum wait time.
     *                    1. {@code value <= 0} and {@code units != null} to return immediately;
     *                    2. {@code value <= 0} and {@code units == null} to wait indefinitely,
     *                    which is same as {@link #blockUntilConnected()}.
     * @param units The time units for the maximum wait time.
     * @return True if connection has been established, false otherwise.
     * @throws InterruptedException If interrupted while waiting
     */
    public boolean blockUntilConnected(int maxWaitTime, TimeUnit units) throws InterruptedException;

    /**
     * Block until a connection to ZooKeeper is available. This method will not return until a
     * connection is available, or it is interrupted, in which case an InterruptedException will
     * be thrown
     * @throws InterruptedException If interrupted while waiting
     */
    public void blockUntilConnected() throws InterruptedException;

    /**
     * Returns a facade of the current instance that tracks
     * watchers created and allows a one-shot removal of all watchers
     * via {@link WatcherRemoveCuratorFramework#removeWatchers()}
     *
     * @return facade
     */
    public WatcherRemoveCuratorFramework newWatcherRemoveCuratorFramework();

    /**
     * Return the configured error policy
     *
     * @return error policy
     */
    public ConnectionStateErrorPolicy getConnectionStateErrorPolicy();

    /**
     * Current maintains a cached view of the Zookeeper quorum config.
     *
     * @return the current config
     */
    public QuorumVerifier getCurrentConfig();

    /**
     * Return this instance's schema set
     *
     * @return schema set
     */
    SchemaSet getSchemaSet();

    /**
     * Calls {@link #notifyAll()} on the given object after first synchronizing on it. This is
     * done from the {@link #runSafe(Runnable)} thread.
     *
     * @param monitorHolder object to sync on and notify
     * @return a CompletableFuture that can be used to monitor when the call is complete
     * @since 4.1.0
     */
    default CompletableFuture<Void> postSafeNotify(Object monitorHolder) {
        return runSafe(() -> {
            synchronized (monitorHolder) {
                monitorHolder.notifyAll();
            }
        });
    }

    /**
     * Curator (and user) recipes can use this to run notifyAll
     * and other blocking calls that might normally block ZooKeeper's event thread.
     *
     * @param runnable proc to call from a safe internal thread
     * @return a CompletableFuture that can be used to monitor when the call is complete
     * @since 4.1.0
     */
    CompletableFuture<Void> runSafe(Runnable runnable);
}
