/*
 * 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.netbeans.modules.profiler.heapwalk;

import org.netbeans.lib.profiler.ProfilerLogger;
import org.netbeans.lib.profiler.global.Platform;
import org.openide.ErrorManager;
import org.openide.util.NbBundle;
import org.openide.util.RequestProcessor;
import org.openide.windows.TopComponent;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.SwingUtilities;
import org.netbeans.modules.profiler.api.ProfilerDialogs;
import org.netbeans.modules.profiler.heapwalk.model.BrowserUtils;
import org.netbeans.modules.profiler.v2.SnapshotsWindow;
import org.openide.filesystems.FileObject;
import org.openide.filesystems.FileUtil;


/**
 * Manages HeapWalker instances & TopComponents
 *
 * @author Jiri Sedlacek
 */
@NbBundle.Messages({
    "HeapWalkerManager_CannotOpenHeapWalkerMsg=Failed to open the heap dump.",
    "HeapWalkerManager_CannotDeleteHeapDumpMsg=<html><b>Deleting heap dump failed</b><br><br>Please try to delete the file once more. If it fails<br>again, restart the IDE and repeat the action.</html>"
})
public class HeapWalkerManager {
    //~ Instance fields ----------------------------------------------------------------------------------------------------------

    private Set dumpsBeingDeleted = new HashSet();
    private List<File> heapDumps = new ArrayList();
    private List<HeapWalker> heapWalkers = new ArrayList();

    final private RequestProcessor heapwalkerRp = new RequestProcessor(HeapWalkerManager.class);

    //~ Constructors -------------------------------------------------------------------------------------------------------------

    private HeapWalkerManager() {
    }

    //~ Methods ------------------------------------------------------------------------------------------------------------------

    private static class Singleton {
        final private static HeapWalkerManager INSTANCE = new HeapWalkerManager();
    }
    
    public static HeapWalkerManager getDefault() {
        return Singleton.INSTANCE;
    }

    public boolean isHeapWalkerOpened(File file) {
        return getHeapWalker(file) != null;
    }

    public void closeAllHeapWalkers() {
        HeapWalker[] heapWalkerArr;
        synchronized (this) {
            heapWalkerArr = heapWalkers.toArray(new HeapWalker[0]);
        }
        for (HeapWalker hw : heapWalkerArr) {
            closeHeapWalker(hw);
        }
    }

    public void closeHeapWalker(final HeapWalker hw) {
        SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    final TopComponent tc = getTopComponent(hw);

                    if (tc == null) {
                        ErrorManager.getDefault().log("Cannot resolve TopComponent for HeapWalker [" + hw.getHeapDumpFile() + "]"); // NOI18N

                        return;
                    }

                    tc.close();
                    FileObject folder = FileUtil.toFileObject(hw.getHeapDumpFile().getParentFile());
                    SnapshotsWindow.instance().refreshFolder(folder, false);
//                    if (ProfilerControlPanel2.hasDefault())
//                        ProfilerControlPanel2.getDefault().refreshSnapshotsList(); // Refresh to display closed HW using plain font
                }
            });
    }

    public void deleteHeapDump(final File file) {
        HeapWalker hw = getHeapWalker(file);

        if (hw != null) {
            dumpsBeingDeleted.add(file);
            closeHeapWalker(hw);
        } else {
            deleteHeapDumpImpl(file, 15);
        }
    }

    // should only be called from HeapWalkerUI.componentClosed
    public synchronized void heapWalkerClosed(HeapWalker hw) {
        final TopComponent tc = getTopComponent(hw);

        if (tc == null) {
            return;
        }

        final File file = hw.getHeapDumpFile();
        heapDumps.remove(file);
        heapWalkers.remove(hw);

        if (dumpsBeingDeleted.remove(file)) {
            BrowserUtils.performTask(new Runnable() {
                    public void run() {
                        deleteHeapDumpImpl(file, 15);
                    }
                });

        }
    }

    public void openHeapWalker(final File heapDump) {
        String heapDumpPath;
        
        try {
            heapDumpPath = heapDump.getCanonicalPath();
        } catch (IOException ex) {
            ProfilerDialogs.displayError(Bundle.HeapWalkerManager_CannotOpenHeapWalkerMsg(), null, ex.getLocalizedMessage());
            return;
        }
        synchronized (heapDumpPath.intern()) {
            HeapWalker hw = getHeapWalker(heapDump);

            if (hw == null) {
                try {
                    hw = new HeapWalker(heapDump);
                } catch (IOException e) {
                    ProfilerDialogs.displayError(Bundle.HeapWalkerManager_CannotOpenHeapWalkerMsg(), null, e.getLocalizedMessage());
                } catch (Exception e) {
                    Logger.getLogger(HeapWalkerManager.class.getName()).log(Level.SEVERE, null, e);
                }
            }

            if (hw != null) {
                openHeapWalker(hw);
            } else {
                ProfilerLogger.severe("Cannot create HeapWalker [" + heapDump + "]"); // NOI18N
            }
        }
    }

    public synchronized void openHeapWalker(final HeapWalker hw) {
        if (!heapWalkers.contains(hw)) {
            heapDumps.add(hw.getHeapDumpFile());
            heapWalkers.add(hw);
        }
        SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    final TopComponent tc = getTopComponent(hw);

                    if (tc == null) {
                        ProfilerLogger.severe("Cannot resolve TopComponent for HeapWalker [" + hw.getHeapDumpFile() + "]"); // NOI18N

                        return;
                    }

                    tc.open();
                    //        tc.requestActive(); // For some reason steals focus from Dump Heap button in ProfilerControlPanel2 and causes http://www.netbeans.org/issues/show_bug.cgi?id=92425
                    tc.requestVisible(); // Workaround for the above problem
                    
                    FileObject folder = FileUtil.toFileObject(hw.getHeapDumpFile().getParentFile());
                    SnapshotsWindow.instance().refreshFolder(folder, false);
//                    if (ProfilerControlPanel2.hasDefault())
//                        ProfilerControlPanel2.getDefault().refreshSnapshotsList(); // Refresh to display opened HW using bold font
                }
            });
    }

    public void openHeapWalkers(File[] heapDumps) {
        for (File heapDump : heapDumps) {
            openHeapWalker(heapDump);
        }
    }

    private synchronized HeapWalker getHeapWalker(File heapDump) {
        int hdIndex = heapDumps.indexOf(heapDump);

        return (hdIndex == -1) ? null : heapWalkers.get(hdIndex);
    }

    private TopComponent getTopComponent(HeapWalker hw) {
        assert SwingUtilities.isEventDispatchThread();
        return hw.getTopComponent();
    }

    private void deleteHeapDumpImpl(final File file, final int retries) {
        heapwalkerRp.post(new Runnable() {
                public void run() {
                    if (!file.delete()) {
                        if ((retries > 0) && Platform.isWindows()) {
                            System.gc();

                            try {
                                Thread.sleep(500);
                            } catch (InterruptedException ex) {
                            }

                            deleteHeapDumpImpl(file, retries - 1);
                        } else {
                            ProfilerDialogs.displayError(Bundle.HeapWalkerManager_CannotDeleteHeapDumpMsg());
                        }
                    } else {
                        FileObject folder = FileUtil.toFileObject(file.getParentFile());
                        SnapshotsWindow.instance().refreshFolder(folder, true);
//                        if (ProfilerControlPanel2.hasDefault())
//                            ProfilerControlPanel2.getDefault().refreshSnapshotsList();
                    }
                }
            });
    }
}
