/*
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.apple.laf;

import java.io.*;
import java.util.*;
import java.util.Map.Entry;

import javax.swing.Icon;
import javax.swing.filechooser.FileView;

import com.apple.laf.AquaUtils.RecyclableSingleton;

class AquaFileView extends FileView {
    private static final boolean DEBUG = false;

    private static final int UNINITALIZED_LS_INFO = -1;

    // Constants from LaunchServices.h
    static final int kLSItemInfoIsPlainFile        = 0x00000001; /* Not a directory, volume, or symlink*/
    static final int kLSItemInfoIsPackage          = 0x00000002; /* Packaged directory*/
    static final int kLSItemInfoIsApplication      = 0x00000004; /* Single-file or packaged application*/
    static final int kLSItemInfoIsContainer        = 0x00000008; /* Directory (includes packages) or volume*/
    static final int kLSItemInfoIsAliasFile        = 0x00000010; /* Alias file (includes sym links)*/
    static final int kLSItemInfoIsSymlink          = 0x00000020; /* UNIX sym link*/
    static final int kLSItemInfoIsInvisible        = 0x00000040; /* Invisible by any known mechanism*/
    static final int kLSItemInfoIsNativeApp        = 0x00000080; /* Carbon or Cocoa native app*/
    static final int kLSItemInfoIsClassicApp       = 0x00000100; /* CFM/68K Classic app*/
    static final int kLSItemInfoAppPrefersNative   = 0x00000200; /* Carbon app that prefers to be launched natively*/
    static final int kLSItemInfoAppPrefersClassic  = 0x00000400; /* Carbon app that prefers to be launched in Classic*/
    static final int kLSItemInfoAppIsScriptable    = 0x00000800; /* App can be scripted*/
    static final int kLSItemInfoIsVolume           = 0x00001000; /* Item is a volume*/
    static final int kLSItemInfoExtensionIsHidden  = 0x00100000; /* Item has a hidden extension*/

    static {
        java.security.AccessController.doPrivileged(
            new java.security.PrivilegedAction<Void>() {
                public Void run() {
                    System.loadLibrary("osxui");
                    return null;
                }
            });
    }

    // TODO: Un-comment this out when the native version exists
    //private static native String getNativePathToRunningJDKBundle();
    private static native String getNativePathToSharedJDKBundle();

    private static native String getNativeMachineName();
    private static native String getNativeDisplayName(final byte[] pathBytes, final boolean isDirectory);
    private static native int getNativeLSInfo(final byte[] pathBytes, final boolean isDirectory);
    private static native String getNativePathForResolvedAlias(final byte[] absolutePath, final boolean isDirectory);

    static final RecyclableSingleton<String> machineName = new RecyclableSingleton<String>() {
        @Override
        protected String getInstance() {
            return getNativeMachineName();
        }
    };
    private static String getMachineName() {
        return machineName.get();
    }

    protected static String getPathToRunningJDKBundle() {
        // TODO: Return empty string for now
        return "";//getNativePathToRunningJDKBundle();
    }

    protected static String getPathToSharedJDKBundle() {
        return getNativePathToSharedJDKBundle();
    }

    static class FileInfo {
        final boolean isDirectory;
        final String absolutePath;
        byte[] pathBytes;

        String displayName;
        Icon icon;
        int launchServicesInfo = UNINITALIZED_LS_INFO;

        FileInfo(final File file){
            isDirectory = file.isDirectory();
            absolutePath = file.getAbsolutePath();
            try {
                pathBytes = absolutePath.getBytes("UTF-8");
            } catch (final UnsupportedEncodingException e) {
                pathBytes = new byte[0];
            }
        }
    }

    final int MAX_CACHED_ENTRIES = 256;
    protected final Map<File, FileInfo> cache = new LinkedHashMap<File, FileInfo>(){
        protected boolean removeEldestEntry(final Entry<File, FileInfo> eldest) {
            return size() > MAX_CACHED_ENTRIES;
        }
    };

    FileInfo getFileInfoFor(final File file) {
        final FileInfo info = cache.get(file);
        if (info != null) return info;
        final FileInfo newInfo = new FileInfo(file);
        cache.put(file, newInfo);
        return newInfo;
    }


    final AquaFileChooserUI fFileChooserUI;
    public AquaFileView(final AquaFileChooserUI fileChooserUI) {
        fFileChooserUI = fileChooserUI;
    }

    String _directoryDescriptionText() {
        return fFileChooserUI.directoryDescriptionText;
    }

    String _fileDescriptionText() {
        return fFileChooserUI.fileDescriptionText;
    }

    boolean _packageIsTraversable() {
        return fFileChooserUI.fPackageIsTraversable == AquaFileChooserUI.kOpenAlways;
    }

    boolean _applicationIsTraversable() {
        return fFileChooserUI.fApplicationIsTraversable == AquaFileChooserUI.kOpenAlways;
    }

    public String getName(final File f) {
        final FileInfo info = getFileInfoFor(f);
        if (info.displayName != null) return info.displayName;

        final String nativeDisplayName = getNativeDisplayName(info.pathBytes, info.isDirectory);
        if (nativeDisplayName != null) {
            info.displayName = nativeDisplayName;
            return nativeDisplayName;
        }

        final String displayName = f.getName();
        if (f.isDirectory() && fFileChooserUI.getFileChooser().getFileSystemView().isRoot(f)) {
            final String localMachineName = getMachineName();
            info.displayName = localMachineName;
            return localMachineName;
        }

        info.displayName = displayName;
        return displayName;
    }

    public String getDescription(final File f) {
        return f.getName();
    }

    public String getTypeDescription(final File f) {
        if (f.isDirectory()) return _directoryDescriptionText();
        return _fileDescriptionText();
    }

    public Icon getIcon(final File f) {
        final FileInfo info = getFileInfoFor(f);
        if (info.icon != null) return info.icon;

        if (f == null) {
            info.icon = AquaIcon.SystemIcon.getDocumentIconUIResource();
        } else {
            // Look for the document's icon
            final AquaIcon.FileIcon fileIcon = new AquaIcon.FileIcon(f);
            info.icon = fileIcon;
            if (!fileIcon.hasIconRef()) {
                // Fall back on the default icons
                if (f.isDirectory()) {
                    if (fFileChooserUI.getFileChooser().getFileSystemView().isRoot(f)) {
                        info.icon = AquaIcon.SystemIcon.getComputerIconUIResource();
                    } else if (f.getParent() == null || f.getParent().equals("/")) {
                        info.icon = AquaIcon.SystemIcon.getHardDriveIconUIResource();
                    } else {
                        info.icon = AquaIcon.SystemIcon.getFolderIconUIResource();
                    }
                } else {
                    info.icon = AquaIcon.SystemIcon.getDocumentIconUIResource();
                }
            }
        }

        return info.icon;
    }

    // aliases are traversable though they aren't directories
    public Boolean isTraversable(final File f) {
        if (f.isDirectory()) {
            // Doesn't matter if it's a package or app, because they're traversable
            if (_packageIsTraversable() && _applicationIsTraversable()) {
                return Boolean.TRUE;
            } else if (!_packageIsTraversable() && !_applicationIsTraversable()) {
                if (isPackage(f) || isApplication(f)) return Boolean.FALSE;
            } else if (!_applicationIsTraversable()) {
                if (isApplication(f)) return Boolean.FALSE;
            } else if (!_packageIsTraversable()) {
                // [3101730] All applications are packages, but not all packages are applications.
                if (isPackage(f) && !isApplication(f)) return Boolean.FALSE;
            }

            // We're allowed to traverse it
            return Boolean.TRUE;
        }

        if (isAlias(f)) {
            final File realFile = resolveAlias(f);
            return realFile.isDirectory() ? Boolean.TRUE : Boolean.FALSE;
        }

        return Boolean.FALSE;
    }

    int getLSInfoFor(final File f) {
        final FileInfo info = getFileInfoFor(f);

        if (info.launchServicesInfo == UNINITALIZED_LS_INFO) {
            info.launchServicesInfo = getNativeLSInfo(info.pathBytes, info.isDirectory);
        }

        return info.launchServicesInfo;
    }

    boolean isAlias(final File f) {
        final int lsInfo = getLSInfoFor(f);
        return ((lsInfo & kLSItemInfoIsAliasFile) != 0) && ((lsInfo & kLSItemInfoIsSymlink) == 0);
    }

    boolean isApplication(final File f) {
        return (getLSInfoFor(f) & kLSItemInfoIsApplication) != 0;
    }

    boolean isPackage(final File f) {
        return (getLSInfoFor(f) & kLSItemInfoIsPackage) != 0;
    }

    /**
     * Things that need to be handled:
     * -Change getFSRef to use CFURLRef instead of FSPathMakeRef
     * -Use the HFS-style path from CFURLRef in resolveAlias() to avoid
     *      path length limitations
     * -In resolveAlias(), simply resolve immediately if this is an alias
     */

    /**
     * Returns the actual file represented by this object.  This will
     * resolve any aliases in the path, including this file if it is an
     * alias.  No alias resolution requiring user interaction (e.g.
     * mounting servers) will occur.  Note that aliases to servers may
     * take a significant amount of time to resolve.  This method
     * currently does not have any provisions for a more fine-grained
     * timeout for alias resolution beyond that used by the system.
     *
     * In the event of a path that does not contain any aliases, or if the file
     *  does not exist, this method will return the file that was passed in.
     *    @return    The canonical path to the file
     *    @throws    IOException    If an I/O error occurs while attempting to
     *                            construct the path
     */
    File resolveAlias(final File mFile) {
        // If the file exists and is not an alias, there aren't
        // any aliases along its path, so the standard version
        // of getCanonicalPath() will work.
        if (mFile.exists() && !isAlias(mFile)) {
            if (DEBUG) System.out.println("not an alias");
            return mFile;
        }

        // If it doesn't exist, either there's an alias in the
        // path or this is an alias.  Traverse the path and
        // resolve all aliases in it.
        final LinkedList<String> components = getPathComponents(mFile);
        if (components == null) {
            if (DEBUG) System.out.println("getPathComponents is null ");
            return mFile;
        }

        File file = new File("/");
        for (final String nextComponent : components) {
            file = new File(file, nextComponent);
            final FileInfo info = getFileInfoFor(file);

            // If any point along the way doesn't exist,
            // just return the file.
            if (!file.exists()) { return mFile; }

            if (isAlias(file)) {
                // Resolve it!
                final String path = getNativePathForResolvedAlias(info.pathBytes, info.isDirectory);

                // <rdar://problem/3582601> If the alias doesn't resolve (on a non-existent volume, for example)
                // just return the file.
                if (path == null) return mFile;

                file = new File(path);
            }
        }

        return file;
    }

    /**
     * Returns a linked list of Strings consisting of the components of
     * the path of this file, in order, including the filename as the
     * last element.  The first element in the list will be the first
     * directory in the path, or "".
     *    @return A linked list of the components of this file's path
     */
    private static LinkedList<String> getPathComponents(final File mFile) {
        final LinkedList<String> componentList = new LinkedList<String>();
        String parent;

        File file = new File(mFile.getAbsolutePath());
        componentList.add(0, file.getName());
        while ((parent = file.getParent()) != null) {
            file = new File(parent);
            componentList.add(0, file.getName());
        }
        return componentList;
    }
}
