/*
 * 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.sling.rewriter.impl;

import java.util.Arrays;

import org.apache.sling.rewriter.ProcessingContext;
import org.apache.sling.rewriter.TransformerFactory;
import org.apache.sling.rewriter.impl.FactoryCache.ServiceReferenceComparator;
import org.apache.sling.rewriter.impl.FactoryCache.TransformerFactoryEntry;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

final class TransformerFactoryServiceTracker<T> extends HashingServiceTrackerCustomizer<T> {

    private final Logger LOGGER = LoggerFactory.getLogger(TransformerFactoryServiceTracker.class);

    private String getMode(final ServiceReference ref) {
        final String mode = (String) ref.getProperty(FactoryCache.PROPERTY_MODE);
        return mode;
    }

    private boolean isGlobal(final ServiceReference ref) {
        return FactoryCache.MODE_GLOBAL.equalsIgnoreCase(this.getMode(ref));
    }

    public static final TransformerFactoryEntry[] EMPTY_ENTRY_ARRAY = new TransformerFactoryEntry[0];
    public static final TransformerFactoryEntry[][] EMPTY_DOUBLE_ENTRY_ARRAY = new TransformerFactoryEntry[][] {EMPTY_ENTRY_ARRAY, EMPTY_ENTRY_ARRAY};

    public static final TransformerFactory[] EMPTY_FACTORY_ARRAY = new TransformerFactory[0];
    public static final TransformerFactory[][] EMPTY_DOUBLE_FACTORY_ARRAY = new TransformerFactory[][] {EMPTY_FACTORY_ARRAY, EMPTY_FACTORY_ARRAY};

    private TransformerFactoryEntry[][] cached = EMPTY_DOUBLE_ENTRY_ARRAY;

    /** flag for cache. */
    private volatile boolean cacheIsValid = true;

    public TransformerFactoryServiceTracker(final BundleContext bc, final String serviceClassName) {
        super(bc, serviceClassName);
    }

    /**
     * @see org.osgi.util.tracker.ServiceTracker#addingService(org.osgi.framework.ServiceReference)
     */
    @Override
    public Object addingService(ServiceReference reference) {
        final boolean isGlobal = isGlobal(reference);
        LOGGER.debug("Adding service {}, isGlobal={}", reference.getClass(), isGlobal);
        Object obj = null;
        synchronized (this) {
            if ( isGlobal ) {
                this.cacheIsValid = false;
            }
            obj = super.addingService(reference);
        }
        if ( obj == null && isGlobal ) {
            obj = this.context.getService(reference);
        }
        return obj;
    }

    /**
     * @see org.osgi.util.tracker.ServiceTracker#removedService(org.osgi.framework.ServiceReference, java.lang.Object)
     */
    @Override
    public void removedService(ServiceReference reference, Object service) {
        final boolean isGlobal = isGlobal(reference);
        LOGGER.debug("Removing service {}, isGlobal={}", reference.getClass(), isGlobal);
        synchronized (this) {
            if ( isGlobal ) {
                this.cacheIsValid = false;
            }
            super.removedService(reference, service);
        }
    }

    /**
     * Get all global transformer factories.
     * @return Two arrays of transformer factories
     */
    public TransformerFactoryEntry[][] getGlobalTransformerFactoryEntries() {
        if ( !this.cacheIsValid ) {
            synchronized ( this ) {
                if ( !this.cacheIsValid ) {
                    final ServiceReference[] refs = this.getServiceReferences();
                    LOGGER.debug("Found {} service references", refs.length);
                    if ( refs == null || refs.length == 0 ) {
                        this.cached = EMPTY_DOUBLE_ENTRY_ARRAY;
                    } else {
                        Arrays.sort(refs, ServiceReferenceComparator.INSTANCE);

                        int preCount = 0;
                        int postCount = 0;
                        for(final ServiceReference ref : refs) {
                            if ( isGlobal(ref) ) {
                                final Object r = ref.getProperty(Constants.SERVICE_RANKING);
                                int ranking = (r instanceof Integer ? (Integer)r : 0);
                                if ( ranking < 0 ) {
                                    preCount++;
                                } else {
                                    postCount++;
                                }
                            }
                        }
                        final TransformerFactoryEntry[][] globalFactories = new TransformerFactoryEntry[2][];
                        if ( preCount == 0 ) {
                            globalFactories[0] = EMPTY_ENTRY_ARRAY;
                        } else {
                            globalFactories[0] = new TransformerFactoryEntry[preCount];
                        }
                        if ( postCount == 0) {
                            globalFactories[1] = EMPTY_ENTRY_ARRAY;
                        } else {
                            globalFactories[1] = new TransformerFactoryEntry[postCount];
                        }
                        int index = 0;
                        for(final ServiceReference ref : refs) {
                            if ( isGlobal(ref) ) {
                                if ( index < preCount ) {
                                    LOGGER.debug("Initializing pre global TransformerFactory for service ref: {}", ref.getClass());
                                    globalFactories[0][index] = new TransformerFactoryEntry((TransformerFactory) this.getService(ref), ref);
                                } else {
                                    LOGGER.debug("Initializing post global TransformerFactory for service ref: {}", ref.getClass());
                                    globalFactories[1][index - preCount] = new TransformerFactoryEntry((TransformerFactory) this.getService(ref), ref);
                                }
                                index++;
                            }
                        }
                        this.cached = globalFactories;
                    }
                }
                this.cacheIsValid = true;
            }
        }

        return this.cached;
    }

    /**
     * Get all global transformer factories that apply to the current request.
     * @param context The current processing context.
     * @return Two arrays containing the transformer factories.
     */
    public TransformerFactory[][] getGlobalTransformerFactories(final ProcessingContext context) {
        final TransformerFactoryEntry[][] globalFactoryEntries = this.getGlobalTransformerFactoryEntries();
        // quick check
        if ( globalFactoryEntries == EMPTY_DOUBLE_ENTRY_ARRAY ) {
            LOGGER.debug("No TransformerFactory found");
            return EMPTY_DOUBLE_FACTORY_ARRAY;
        }
        final TransformerFactory[][] factories = new TransformerFactory[2][];
        for(int i=0; i<2; i++) {
            if ( globalFactoryEntries[i] == EMPTY_ENTRY_ARRAY ) {
                LOGGER.debug("No {} TransformerFactory found for context {}", i == 0 ? "pre" : "post", context);
                factories[i] = EMPTY_FACTORY_ARRAY;
            } else {
                factories[i] = new TransformerFactory[globalFactoryEntries[i].length];
                for(int m=0; m<globalFactoryEntries[i].length; m++) {
                    final TransformerFactoryEntry entry = globalFactoryEntries[i][m];
                    if ( entry.match(context) ) {
                        factories[i][m] = entry.factory;
                    }
                }
                LOGGER.debug("Found {} Transformer factories {} for context {}", i == 0 ? "pre" : "post", factories[i], context);
            }
        }
        return factories;
    }
}