/*
 * The contents of this file are subject to the terms of the Common Development
 * and Distribution License (the License). You may not use this file except in
 * compliance with the License.
 *
 * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
 * or http://www.netbeans.org/cddl.txt.
 * 
 * When distributing Covered Code, include this CDDL Header Notice in each file
 * and include the License file at http://www.netbeans.org/cddl.txt.
 * If applicable, add the following below the CDDL Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
 * Microsystems, Inc. All Rights Reserved.
 */

package org.netbeans.modules.masterfs;

import org.openide.filesystems.FileSystem;
import org.openide.util.Lookup;
import org.openide.util.LookupListener;
import org.openide.util.LookupEvent;
import org.netbeans.modules.masterfs.providers.AutoMountProvider;
import org.netbeans.modules.masterfs.providers.FileSystemProvider;

import java.io.IOException;
import java.beans.PropertyVetoException;
import java.util.*;
import java.awt.*;

public class ProviderCall {
    static private Map providerMap;
    static private Lookup.Result preventsLookupResultFromGC;

    static void init () {
        getProviderMap();    
    }
    
    static FileSystem createFileSystem(String resName) {
        FileSystem retVal = null;

        AutoMountProvider ap = getMountAble(resName);

        if (ap != null) {
            try {
                retVal = ap.createFileSystem(resName);
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            } catch (PropertyVetoException e) {
                e.printStackTrace();
                return null;
            }
        }

        return retVal;
    }


    static boolean isMountAble(String resName) {
        return getMountAble(resName) == null ? false : true;
    }

    static Image getIcon(String resName, int iconType) {
        Image icon = null;
        AutoMountProvider aProvider = ProviderCall.getMountAble(resName);
        if (aProvider != null) {
            icon = aProvider.getIcon(resName, iconType);
        }
        return icon;
    }


    private static AutoMountProvider getMountAble(String resName) {
        Map providerMapCopy;
        synchronized (getProviderMap()) {
            providerMapCopy = new HashMap(getProviderMap());
        }

        Iterator it = providerMapCopy.values().iterator();
        while (it.hasNext()) {
            AutoMountProvider aProvider = (AutoMountProvider) it.next();
            if (aProvider == null) continue;
            boolean retVal = aProvider.isRootOfFileSystem(resName);
            if (retVal) return aProvider;
        }

        return null;
    }

//    }

    static private Map getProviderMap() {
        synchronized (MasterFileSystem.class) {
            if (providerMap == null) {
                providerMap = Collections.synchronizedMap(new HashMap());
                final Lookup.Result providerResult =
                        Lookup.getDefault().lookup(new Lookup.Template(FileSystemProvider.class));
                preventsLookupResultFromGC = providerResult;
                initFileSystemProviders(providerResult);
                providerResult.addLookupListener(new LookupListener() {
                    public void resultChanged(LookupEvent ev) {
                        initFileSystemProviders(providerResult);
                    }
                });
            }
        }
        return providerMap;
    }

    static private void initFileSystemProviders(Lookup.Result result) {
        Set newProviders = new HashSet(result.allInstances());                
        
        Map upToDateMap = new HashMap(newProviders.size());
        Iterator it = newProviders.iterator();
        while (it.hasNext()) {
            FileSystemProvider provider = (FileSystemProvider) it.next();
            AutoMountProvider aProvider = (AutoMountProvider) getProviderMap().get(provider);
            if (aProvider == null) {
                if (!getProviderMap().keySet().contains(provider)) {
                    aProvider = provider.initialize(MountTable.getDefault().mountSupport);
                }
            }
            upToDateMap.put(provider, aProvider);
        }
        getProviderMap().clear();
        getProviderMap().putAll(upToDateMap);
    }

}
