/*
 * 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.search;

import java.awt.EventQueue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.netbeans.api.progress.ProgressHandle;
import org.netbeans.api.progress.ProgressHandleFactory;
import org.netbeans.modules.search.MatchingObject.InvalidityStatus;
import org.netbeans.modules.search.ui.BasicReplaceResultsPanel;
import org.openide.filesystems.FileAlreadyLockedException;
import org.openide.filesystems.FileLock;
import org.openide.filesystems.FileUtil;
import org.openide.util.NbBundle;
import org.openide.util.UserQuestionException;

/**
 * Task that checks validity of found files and then
 * (if everything is valid) replaces the matching substrings
 * with the replacement string/pattern.
 * 
 * @author  Tim Boudreau
 * @author  Marian Petras
 */
public final class ReplaceTask implements Runnable {
    
    /**
     * maximum number of errors detected before replacing
     * and displayed to the user
     */
    private static final int MAX_ERRORS_CHECKED = 20;
    
    private final List<MatchingObject> matchingObjects;
    private final ProgressHandle progressHandle;
    private final List<String> problems;
    private final BasicReplaceResultsPanel panel;
    
    /** */
    private ResultStatus resultStatus = null;
    
    enum ResultStatus {
        SUCCESS,
        PRE_CHECK_FAILED,
        PROBLEMS_ENCOUNTERED
    }
    
    /**
     */
    public ReplaceTask(List<MatchingObject> matchingObjects,
            BasicReplaceResultsPanel panel) {
        this.matchingObjects = matchingObjects;
        this.panel = panel;
        
        problems = new ArrayList<String>(4);
        progressHandle = ProgressHandleFactory.createHandle(
                NbBundle.getMessage(getClass(), "LBL_Replacing"), //NOI18N
                null, null);
    }
    
    /**
     */
    public void run() {
        assert !EventQueue.isDispatchThread();
        
        progressHandle.start(matchingObjects.size() * 2);
        try {
            replace();
            assert resultStatus != null;
        } finally {
            progressHandle.finish();
        }
    }
    
    /**
     */
    private void replace() {
        assert !EventQueue.isDispatchThread();
        
        checkForErrors();
        if (resultStatus == null) {       //the check passed
            FileUtil.runAtomicAction(new Runnable() {
                public void run() {
                    doReplace();
                }
            });
        }
    }
    
    /**
     */
    private void checkForErrors() {
        assert !EventQueue.isDispatchThread();
        
        int errorsCount = 0;
        
        for(MatchingObject mo: matchingObjects) {
            InvalidityStatus status = mo.checkValidity();
            if (status != null) {
                problems.add(status.getDescription(mo.getFileObject().getPath()));
                if (++errorsCount > MAX_ERRORS_CHECKED) {
                    break;
                }
            }
        }
        if (!problems.isEmpty()) {
            resultStatus = ResultStatus.PRE_CHECK_FAILED;
        }
    }

    /**
     * 
     * @return  list of strings describing problems that happened during
     *          the replace, or {@code null} if no problem happened
     */
    private void doReplace() {
        assert !EventQueue.isDispatchThread();

        int i = 0;
        int moSize = matchingObjects.size();
        for(final MatchingObject obj: matchingObjects) {
            int workunit = moSize + i++;
            progressHandle.progress(obj.getName(), workunit);
            if (!obj.isSelected() || !obj.isValid()) {
                continue;
            }
            
            String invDescription = obj.getInvalidityDescription();
            if (invDescription != null) {
                problems.add(invDescription);
                continue;
            }
            
            String errMessage = null;
            FileLock fileLock = null;
            try {
                fileLock = obj.lock();
                MatchingObject.InvalidityStatus status = obj.replace();
                if (status == null) {
                    obj.write(fileLock);
                } else {
                    errMessage = status.getDescription(obj.getFileObject().getPath());
                }
            } catch (FileAlreadyLockedException ex) {
                errMessage = createMsgFileLocked(obj);
            } catch (UserQuestionException ex) {
                errMessage = createMsgFileLocked(obj);
            } catch (IOException ex) {
                ex.printStackTrace();      //PENDING - ex.printStackTrace()?
                errMessage = ex.getLocalizedMessage();
                if (errMessage == null) {
                    errMessage = ex.getMessage();
                }
            } finally {
                if (fileLock != null) {
                    fileLock.releaseLock();
                }
            }
            if (errMessage != null) {
                problems.add(errMessage);
            }
        }
        resultStatus = problems.isEmpty() ? ResultStatus.SUCCESS
                                          : ResultStatus.PROBLEMS_ENCOUNTERED;
    }

    private static String createMsgFileLocked(MatchingObject matchingObj) {
        return NbBundle.getMessage(
                ReplaceTask.class,
                "MSG_cannot_access_file_already_locked",                //NOI18N
                matchingObj.getName());
    }
    
    /**
     * 
     * @see  #getProblems()
     */
    ResultStatus getResultStatus() {
        return resultStatus;
    }
    
    /**
     * Returns a list of problems encountered during the pre-check or 
     * during replacing. The type of problems (pre-check or replacing)
     * can be determined from the results status returned by method
     * {@link #getResultStatus()}.
     * 
     * @return  array of problems, or {@code null} if no problems have been
     *          encountered
     * @see  #getResultStatus()
     */
    String[] getProblems() {
        return problems.isEmpty()
               ? null
               : problems.toArray(new String[problems.size()]);
    }

    BasicReplaceResultsPanel getPanel() {
        return panel;
    }
}
