/*
 * Copyright (C) 2012 The Android Open Source Project
 *
 * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php
 *
 * 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 com.android.ide.eclipse.adt.internal.lint;

import static com.android.SdkConstants.DOT_CLASS;
import static com.android.SdkConstants.DOT_JAVA;
import static com.android.SdkConstants.EXT_JAVA;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.AdtUtils;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor;
import com.android.ide.eclipse.adt.internal.resources.manager.GlobalProjectMonitor.IFileListener;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;

import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarkerDelta;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceDelta;
import org.eclipse.swt.widgets.Display;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Delta processor for Java files, which runs single-file lints if it finds that
 * the currently active file has been updated.
 */
public class LintDeltaProcessor implements Runnable {
    private List<IResource> mFiles;
    private IFile mActiveFile;

    private LintDeltaProcessor() {
        // Get the active editor file, if any
        Display display = AdtPlugin.getDisplay();
        if (display == null || display.isDisposed()) {
            return;
        }
        if (display.getThread() != Thread.currentThread()) {
            display.syncExec(this);
        } else {
            run();
        }
    }

    /**
     * Creates a new {@link LintDeltaProcessor}
     *
     * @return a visitor
     */
    @NonNull
    public static LintDeltaProcessor create() {
        return new LintDeltaProcessor();
    }

    /**
     * Process the given delta: update lint on any Java source and class files found.
     *
     * @param delta the delta describing recently changed files
     */
    public void process(@NonNull IResourceDelta delta)  {
        if (mActiveFile == null || !mActiveFile.getName().endsWith(DOT_JAVA)) {
            return;
        }

        mFiles = new ArrayList<IResource>();
        gatherFiles(delta);

        if (!mFiles.isEmpty()) {
            EclipseLintRunner.startLint(mFiles, mActiveFile, null,
                    false /*fatalOnly*/, false /*show*/);
        }
    }

    /**
     * Process edits in the given file: update lint on the Java source provided
     * it's the active file.
     *
     * @param file the file that was changed
     */
    public void process(@NonNull IFile file)  {
        if (mActiveFile == null || !mActiveFile.getName().endsWith(DOT_JAVA)) {
            return;
        }

        if (file.equals(mActiveFile)) {
            mFiles = Collections.<IResource>singletonList(file);
            EclipseLintRunner.startLint(mFiles, mActiveFile, null,
                    false /*fatalOnly*/, false /*show*/);
        }
    }

    /**
     * Collect .java and .class files to be run in lint. Only collects files
     * that match the active editor.
     */
    private void gatherFiles(@NonNull IResourceDelta delta) {
        IResource resource = delta.getResource();
        String name = resource.getName();
        if (name.endsWith(DOT_JAVA)) {
            if (resource.equals(mActiveFile)) {
                mFiles.add(resource);
            }
        } else if (name.endsWith(DOT_CLASS)) {
            // Make sure this class corresponds to the .java file, meaning it has
            // the same basename, or that it is an inner class of a class that
            // matches the same basename. (We could potentially make sure the package
            // names match too, but it's unlikely that the class names match without a
            // package match, and there's no harm in including some extra classes here,
            // since lint will resolve full paths and the resource markers won't go
            // to the wrong place, we simply end up analyzing some extra files.)
            String className = mActiveFile.getName();
            if (name.regionMatches(0, className, 0, className.length() - DOT_JAVA.length())) {
                if (name.length() == className.length() - DOT_JAVA.length() + DOT_CLASS.length()
                        || name.charAt(className.length() - DOT_JAVA.length()) == '$') {
                    mFiles.add(resource);
                }
            }
        } else {
            IResourceDelta[] children = delta.getAffectedChildren();
            if (children != null && children.length > 0) {
                for (IResourceDelta d : children) {
                    gatherFiles(d);
                }
            }
        }
    }

    @Override
    public void run() {
        // Get the active file: this must be run on the GUI thread
        mActiveFile = AdtUtils.getActiveFile();
    }

    /**
     * Start listening to the resource monitor
     *
     * @param resourceMonitor the resource monitor
     */
    public static void startListening(@NonNull GlobalProjectMonitor resourceMonitor) {
        // Add a file listener which finds out when files have changed. This is listening
        // specifically for saves of Java files, in order to run incremental lint on them.
        // Note that the {@link PostCompilerBuilder} already handles incremental lint files
        // on Java files - and runs it for both the .java and .class files.
        //
        // However, if Project > Build Automatically is turned off, then the PostCompilerBuilder
        // isn't run after a save. THAT's what the below is for: it will run and *only*
        // run lint incrementally if build automatically is off.
        assert sListener == null; // Should only be called once on plugin activation
        sListener = new IFileListener() {
            @Override
            public void fileChanged(@NonNull IFile file,
                    @NonNull IMarkerDelta[] markerDeltas,
                    int kind, @Nullable String extension, int flags, boolean isAndroidProject) {
                if (!isAndroidProject || flags == IResourceDelta.MARKERS) {
                    // If not an Android project or ONLY the markers changed.
                    // Ignore these since they happen
                    // when we add markers for lint errors found in the current file,
                    // which would cause us to repeatedly enter this method over and over
                    // again.
                    return;
                }
                if (EXT_JAVA.equals(extension)
                        && !ResourceManager.isAutoBuilding()
                        && AdtPrefs.getPrefs().isLintOnSave()) {
                    LintDeltaProcessor.create().process(file);
                }
            }
        };
        resourceMonitor.addFileListener(sListener, IResourceDelta.ADDED | IResourceDelta.CHANGED);
    }

    /**
     * Stop listening to the resource monitor
     *
     * @param resourceMonitor the resource monitor
     */
    public static void stopListening(@NonNull GlobalProjectMonitor resourceMonitor) {
        assert sListener != null;
        resourceMonitor.removeFileListener(sListener);
        sListener = null;
    }

    private static IFileListener sListener;
}
