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

import java.io.PrintWriter;
import java.io.Serializable;
import java.io.StringWriter;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import org.apache.ignite.IgniteCheckedException;
import org.apache.ignite.IgniteClientDisconnectedException;
import org.apache.ignite.internal.util.StripedCompositeReadWriteLock;
import org.apache.ignite.internal.util.future.GridFutureAdapter;
import org.apache.ignite.internal.util.future.IgniteFutureImpl;
import org.apache.ignite.internal.util.tostring.GridToStringExclude;
import org.apache.ignite.internal.util.typedef.internal.S;

/**
 *
 */
@GridToStringExclude
public class GridKernalGatewayImpl implements GridKernalGateway, Serializable {
    /** */
    private static final long serialVersionUID = 0L;

    /** */
    @GridToStringExclude
    private final ReadWriteLock rwLock =
        new StripedCompositeReadWriteLock(Runtime.getRuntime().availableProcessors());

    /** */
    @GridToStringExclude
    private volatile IgniteFutureImpl<?> reconnectFut;

    /** */
    private final AtomicReference<GridKernalState> state = new AtomicReference<>(GridKernalState.STOPPED);

    /** */
    @GridToStringExclude
    private final String igniteInstanceName;

    /**
     * User stack trace.
     *
     * Intentionally uses non-volatile variable for optimization purposes.
     */
    private String stackTrace;

    /**
     * @param igniteInstanceName Ignite instance name.
     */
    public GridKernalGatewayImpl(String igniteInstanceName) {
        this.igniteInstanceName = igniteInstanceName;
    }

    /** {@inheritDoc} */
    @SuppressWarnings({"LockAcquiredButNotSafelyReleased", "BusyWait"})
    @Override public void readLock() throws IllegalStateException {
        if (stackTrace == null)
            stackTrace = stackTrace();

        Lock lock = rwLock.readLock();

        lock.lock();

        GridKernalState state = this.state.get();

        if (state != GridKernalState.STARTED) {
            // Unlock just acquired lock.
            lock.unlock();

            if (state == GridKernalState.DISCONNECTED) {
                assert reconnectFut != null;

                throw new IgniteClientDisconnectedException(reconnectFut, "Client node disconnected: " + igniteInstanceName);
            }

            throw illegalState();
        }
    }

    /** {@inheritDoc} */
    @Override public void readLockAnyway() {
        if (stackTrace == null)
            stackTrace = stackTrace();

        rwLock.readLock().lock();

        if (state.get() == GridKernalState.DISCONNECTED)
            throw new IgniteClientDisconnectedException(reconnectFut, "Client node disconnected: " + igniteInstanceName);
    }

    /** {@inheritDoc} */
    @Override public void readUnlock() {
        rwLock.readLock().unlock();
    }

    /** {@inheritDoc} */
    @SuppressWarnings({"BusyWait"})
    @Override public void writeLock() {
        if (stackTrace == null)
            stackTrace = stackTrace();

        boolean interrupted = false;

        // Busy wait is intentional.
        while (true)
            try {
                if (rwLock.writeLock().tryLock(200, TimeUnit.MILLISECONDS))
                    break;
                else
                    Thread.sleep(200);
            }
            catch (InterruptedException ignore) {
                // Preserve interrupt status & ignore.
                // Note that interrupted flag is cleared.
                interrupted = true;
            }

        if (interrupted)
            Thread.currentThread().interrupt();
    }

    /** {@inheritDoc} */
    @Override public boolean tryWriteLock(long timeout) throws InterruptedException {
        boolean acquired = rwLock.writeLock().tryLock(timeout, TimeUnit.MILLISECONDS);

        if (acquired) {
            if (stackTrace == null)
                stackTrace = stackTrace();

            return true;
        }

        return false;
    }

    /** {@inheritDoc} */
    @Override public GridFutureAdapter<?> onDisconnected() {
        if (state.get() == GridKernalState.DISCONNECTED) {
            assert reconnectFut != null;

            return (GridFutureAdapter<?>)reconnectFut.internalFuture();
        }

        GridFutureAdapter<?> fut = new GridFutureAdapter<>();

        reconnectFut = new IgniteFutureImpl<>(fut);

        if (!state.compareAndSet(GridKernalState.STARTED, GridKernalState.DISCONNECTED)) {
            ((GridFutureAdapter<?>)reconnectFut.internalFuture()).onDone(new IgniteCheckedException("Node stopped."));

            return null;
        }

        return fut;
    }

    /** {@inheritDoc} */
    @Override public void onReconnected() {
        if (state.compareAndSet(GridKernalState.DISCONNECTED, GridKernalState.STARTED))
            ((GridFutureAdapter<?>)reconnectFut.internalFuture()).onDone();
    }

    /**
     * Retrieves user stack trace.
     *
     * @return User stack trace.
     */
    private static String stackTrace() {
        StringWriter sw = new StringWriter();

        new Throwable().printStackTrace(new PrintWriter(sw));

        return sw.toString();
    }

    /**
     * Creates new illegal state exception.
     *
     * @return Newly created exception.
     */
    private IllegalStateException illegalState() {
        return new IllegalStateException("Grid is in invalid state to perform this operation. " +
            "It either not started yet or has already being or have stopped [igniteInstanceName=" + igniteInstanceName +
            ", state=" + state + ']');
    }

    /** {@inheritDoc} */
    @Override public void writeUnlock() {
        rwLock.writeLock().unlock();
    }

    /** {@inheritDoc} */
    @Override public void setState(GridKernalState state) {
        assert state != null;

        // NOTE: this method should always be called within write lock.
        this.state.set(state);

        if (reconnectFut != null)
            ((GridFutureAdapter<?>)reconnectFut.internalFuture()).onDone(new IgniteCheckedException("Node stopped."));
    }

    /** {@inheritDoc} */
    @Override public GridKernalState getState() {
        return state.get();
    }

    /** {@inheritDoc} */
    @Override public String userStackTrace() {
        return stackTrace;
    }

    /** {@inheritDoc} */
    @Override public String toString() {
        return S.toString(GridKernalGatewayImpl.class, this);
    }
}
