/*
 * 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.felix.scr.impl.manager;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

import org.osgi.service.log.LogService;

abstract class RegistrationManager<T>
{
    enum RegState {unregistered, registered};
    private static class RegStateWrapper
    {
        private final CountDownLatch latch = new CountDownLatch(1);
        private final RegState regState;

        RegStateWrapper( RegState regState )
        {
            this.regState = regState;
        }

        public RegState getRegState()
        {
            return regState;
        }

        public CountDownLatch getLatch()
        {
            return latch;
        }

        @Override
        public int hashCode()
        {
            return regState.hashCode();
        }

        @Override
        public boolean equals(Object other)
        {
            return other instanceof RegStateWrapper && regState == ((RegStateWrapper)other).getRegState();
        }

        @Override
        public String toString()
        {
            return regState.toString();
        }

    }
    private final Lock registrationLock = new ReentrantLock();
    //Deque, ArrayDeque if we had java 6
    private final List<RegStateWrapper> opqueue = new ArrayList<>();

    private volatile T m_serviceRegistration;

    /**
     *
     * @param desired desired registration state
     * @param services services to register this under
     * @return true if this request results in a state change, false if we are already in the desired state or some other thread
     * will deal with the consequences of the state change.
     */
    boolean changeRegistration( RegState desired, String[] services )
    {
        RegStateWrapper rsw = null;
        registrationLock.lock();
        try
        {
            if (opqueue.isEmpty())
            {
                if ((desired == RegState.unregistered) == (m_serviceRegistration == null))
                {
                    log( LogService.LOG_DEBUG, "Already in desired state {0}", null, desired);
                    return false;
                }
            }
            else if (opqueue.get( opqueue.size() - 1 ).getRegState() == desired)
            {
                log( LogService.LOG_DEBUG, "Duplicate request on other thread: registration change queue {0}", null, opqueue);
                rsw = opqueue.get( opqueue.size() - 1 );
                return false; //another thread will do our work and owns the state change
            }
            rsw = new RegStateWrapper( desired );
            opqueue.add( rsw );
            if (opqueue.size() > 1)
            {
                log( LogService.LOG_DEBUG, "Allowing other thread to process request: registration change queue {0}", null, opqueue);
                return true; //some other thread will do it later but this thread owns the state change.
            }
            //we're next
            do
            {
                log( LogService.LOG_DEBUG, "registration change queue {0}", null, opqueue);;
                RegStateWrapper next = opqueue.get( 0 );
                T serviceRegistration = m_serviceRegistration;
                if ( next.getRegState() == RegState.unregistered)
                {
                    m_serviceRegistration = null;
                }

                registrationLock.unlock();
                try
                {
                    if (next.getRegState() == RegState.registered)
                    {
                        serviceRegistration = register(services );

                    }
                    else
                    {
                        if ( serviceRegistration != null )
                        {
                            unregister( serviceRegistration );
                        }
                        else
                        {
                            log( LogService.LOG_ERROR, "Unexpected unregistration request with no registration present",  new Exception("Stack trace"));

                        }
                    }
                }
                finally
                {
                    registrationLock.lock();
                    opqueue.remove(0);
                    if ( next.getRegState() == RegState.registered)
                    {
                        m_serviceRegistration = serviceRegistration;
                        postRegister( m_serviceRegistration );
                    }
                    next.getLatch().countDown();
                }
            }
            while (!opqueue.isEmpty());
            return true;
        }
        finally
        {
            registrationLock.unlock();
            if (rsw != null)
            {
                try
                {
                    if ( !rsw.getLatch().await( getTimeout(), TimeUnit.MILLISECONDS ))
                    {
                        log( LogService.LOG_ERROR, "Timeout waiting for reg change to complete {0}", null, rsw.getRegState());
                        reportTimeout();
                    }
                }
                catch ( InterruptedException e )
                {
                    try
                    {
                        if ( !rsw.getLatch().await( getTimeout(), TimeUnit.MILLISECONDS ))
                        {
                            log( LogService.LOG_ERROR, "Timeout waiting for reg change to complete {0}", null, rsw.getRegState());
                            reportTimeout();
                        }
                    }
                    catch ( InterruptedException e1 )
                    {
                        log( LogService.LOG_ERROR, "Interrupted twice waiting for reg change to complete {0}",null, rsw.getRegState());
                    }
                    Thread.currentThread().interrupt();
                }
            }
        }

    }

    abstract T register(String[] services);

    abstract void postRegister(T t);

    abstract void unregister(T serviceRegistration);

    abstract void log( int level, String message, Throwable ex, Object... arguments );

    abstract long getTimeout();

    abstract void reportTimeout();

    T getServiceRegistration()
    {
        return m_serviceRegistration;
    }

}
