/*
 * 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.commons.vfs2.cache;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import org.apache.commons.vfs2.FileName;
import org.apache.commons.vfs2.FileObject;
import org.apache.commons.vfs2.FileSystem;

/**
 * A simple {@link org.apache.commons.vfs2.FilesCache FilesCache} implementation.
 * <p>
 * This implementation caches every file with no expire or limit.
 * All files and filesystems are hard reachable references. This implementation
 * holds a list of filesystem specific {@linkplain ConcurrentHashMap ConcurrentHashMaps} in
 * the main cache map.
 * <p>
 * Cached {@linkplain FileObject FileObjects} as well as {@linkplain FileSystem FileSystems}
 * are only removed when {@link #clear(FileSystem)} is called (i.e. on filesystem close).
 * When the used {@link org.apache.commons.vfs2.FileSystemManager FileSystemManager} is closed,
 * it will also {@linkplain #close() close} this cache (which frees all entries).
 * <p>
 * Despite its name, this is not the fallback implementation used by
 * {@link org.apache.commons.vfs2.impl.DefaultFileSystemManager#init() DefaultFileSystemManager#init()}
 * anymore.
 */
public class DefaultFilesCache extends AbstractFilesCache
{
    /** The FileSystem cache. Keeps one Map for each FileSystem. */
    private final ConcurrentMap<FileSystem, ConcurrentMap<FileName, FileObject>> filesystemCache =
                    new ConcurrentHashMap<FileSystem, ConcurrentMap<FileName, FileObject>>(10);

    @Override
    public void putFile(final FileObject file)
    {
        final Map<FileName, FileObject> files = getOrCreateFilesystemCache(file.getFileSystem());
        files.put(file.getName(), file);
    }

    @Override
    public boolean putFileIfAbsent(final FileObject file)
    {
        final ConcurrentMap<FileName, FileObject> files = getOrCreateFilesystemCache(file.getFileSystem());
        return files.putIfAbsent(file.getName(), file) == null;
    }

    @Override
    public FileObject getFile(final FileSystem filesystem, final FileName name)
    {
        // avoid creating filesystem entry for empty filesystem cache:
        final Map<FileName, FileObject> files = filesystemCache.get(filesystem);
        if (files == null)
        {
            // cache for filesystem is not known => file is not cached:
            return null;
        }

        return files.get(name); // or null
    }

    @Override
    public void clear(final FileSystem filesystem)
    {
        // avoid keeping a reference to the FileSystem (key) object
        final Map<FileName, FileObject> files = filesystemCache.remove(filesystem);
        if (files != null)
        {
            files.clear(); // help GC
        }
    }

    protected ConcurrentMap<FileName, FileObject> getOrCreateFilesystemCache(final FileSystem filesystem)
    {
        ConcurrentMap<FileName, FileObject> files = filesystemCache.get(filesystem);
        // we loop to make sure we never return null even when concurrent clean is called
        while (files == null)
        {
            filesystemCache.putIfAbsent(filesystem, new ConcurrentHashMap<FileName, FileObject>(200, 0.75f, 8));
            files = filesystemCache.get(filesystem);
        }

        return files;
    }

    @Override
    public void close()
    {
        super.close();

        filesystemCache.clear();
    }

    @Override
    public void removeFile(final FileSystem filesystem, final FileName name)
    {
        // avoid creating filesystem entry for empty filesystem cache:
        final Map<FileName, FileObject> files = filesystemCache.get(filesystem);
        if (files != null)
        {
            files.remove(name);
            // This would be too racey:
            // if (files.empty()) filesystemCache.remove(filessystem);
        }
    }
}
