/*
 * Copyright (C) 2011 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 com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.tools.lint.client.api.IssueRegistry;

import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.text.IDocument;
import org.eclipse.swt.widgets.Shell;

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

/**
 * Eclipse implementation for running lint on workspace files and projects.
 */
public class EclipseLintRunner {
    static final String MARKER_CHECKID_PROPERTY = "checkid";    //$NON-NLS-1$

    /**
     * Runs lint and updates the markers, and waits for the result. Returns
     * true if fatal errors were found.
     *
     * @param resources the resources (project, folder or file) to be analyzed
     * @param source if checking a single source file, the source file
     * @param doc the associated document, if known, or null
     * @param fatalOnly if true, only report fatal issues (severity=error)
     * @return true if any fatal errors were encountered.
     */
    private static boolean runLint(
            @NonNull List<? extends IResource> resources,
            @Nullable IResource source,
            @Nullable IDocument doc,
            boolean fatalOnly) {
        resources = addLibraries(resources);
        LintJob job = (LintJob) startLint(resources, source,  doc, fatalOnly,
                false /*show*/);
        try {
            job.join();
            boolean fatal = job.isFatal();

            if (fatal) {
                LintViewPart.show(resources);
            }

            return fatal;
        } catch (InterruptedException e) {
            AdtPlugin.log(e, null);
        }

        return false;
    }

    /**
     * Runs lint and updates the markers. Does not wait for the job to finish -
     * just returns immediately.
     *
     * @param resources the resources (project, folder or file) to be analyzed
     * @param source if checking a single source file, the source file. When
     *            single checking an XML file, this is typically the same as the
     *            file passed in the list in the first parameter, but when
     *            checking the .class files of a Java file for example, the
     *            .class file and all the inner classes of the Java file are
     *            passed in the first parameter, and the corresponding .java
     *            source file is passed here.
     * @param doc the associated document, if known, or null
     * @param fatalOnly if true, only report fatal issues (severity=error)
     * @param show if true, show the results in a {@link LintViewPart}
     * @return the job running lint in the background.
     */
    public static Job startLint(
            @NonNull List<? extends IResource> resources,
            @Nullable IResource source,
            @Nullable IDocument doc,
            boolean fatalOnly,
            boolean show) {
        IssueRegistry registry = EclipseLintClient.getRegistry();
        EclipseLintClient client = new EclipseLintClient(registry, resources, doc, fatalOnly);
        return startLint(client, resources, source, show);
    }

    /**
     * Runs lint and updates the markers. Does not wait for the job to finish -
     * just returns immediately.
     *
     * @param client the lint client receiving issue reports etc
     * @param resources the resources (project, folder or file) to be analyzed
     * @param source if checking a single source file, the source file. When
     *            single checking an XML file, this is typically the same as the
     *            file passed in the list in the first parameter, but when
     *            checking the .class files of a Java file for example, the
     *            .class file and all the inner classes of the Java file are
     *            passed in the first parameter, and the corresponding .java
     *            source file is passed here.
     * @param show if true, show the results in a {@link LintViewPart}
     * @return the job running lint in the background.
     */
    public static Job startLint(
            @NonNull EclipseLintClient client,
            @NonNull List<? extends IResource> resources,
            @Nullable IResource source,
            boolean show) {
        if (resources != null && !resources.isEmpty()) {
            if (!AdtPrefs.getPrefs().getSkipLibrariesFromLint()) {
                resources = addLibraries(resources);
            }

            cancelCurrentJobs(false);

            LintJob job = new LintJob(client, resources, source);
            job.schedule();

            if (show) {
                // Show lint view where the results are listed
                LintViewPart.show(resources);
            }
            return job;
        }

        return null;
    }

    /**
     * Run Lint for an Export APK action. If it succeeds (no fatal errors)
     * returns true, and if it fails it will display an error message and return
     * false.
     *
     * @param shell the parent shell to show error messages in
     * @param project the project to run lint on
     * @return true if the lint run succeeded with no fatal errors
     */
    public static boolean runLintOnExport(Shell shell, IProject project) {
        if (AdtPrefs.getPrefs().isLintOnExport()) {
            boolean fatal = EclipseLintRunner.runLint(Collections.singletonList(project),
                    null, null, true /*fatalOnly*/);
            if (fatal) {
                MessageDialog.openWarning(shell,
                        "Export Aborted",
                        "Export aborted because fatal lint errors were found. These " +
                        "are listed in the Lint View. Either fix these before " +
                        "running Export again, or turn off \"Run full error check " +
                        "when exporting app\" in the Android > Lint Error Checking " +
                        "preference page.");
                return false;
            }
        }

        return true;
    }

    /** Cancels the current lint jobs, if any, and optionally waits for them to finish */
    static void cancelCurrentJobs(boolean wait) {
        // Cancel any current running jobs first
        Job[] currentJobs = LintJob.getCurrentJobs();
        for (Job job : currentJobs) {
            job.cancel();
        }

        if (wait) {
            for (Job job : currentJobs) {
                try {
                    job.join();
                } catch (InterruptedException e) {
                    AdtPlugin.log(e, null);
                }
            }
        }
    }

    /** If the resource list contains projects, add in any library projects as well */
    private static List<? extends IResource> addLibraries(List<? extends IResource> resources) {
        if (resources != null && !resources.isEmpty()) {
            boolean haveProjects = false;
            for (IResource resource : resources) {
                if (resource instanceof IProject) {
                    haveProjects = true;
                    break;
                }
            }

            if (haveProjects) {
                List<IResource> result = new ArrayList<IResource>();
                Map<IProject, IProject> allProjects = new IdentityHashMap<IProject, IProject>();
                List<IProject> projects = new ArrayList<IProject>();
                for (IResource resource : resources) {
                    if (resource instanceof IProject) {
                        IProject project = (IProject) resource;
                        allProjects.put(project, project);
                        projects.add(project);
                    } else {
                        result.add(resource);
                    }
                }
                for (IProject project : projects) {
                    ProjectState state = Sdk.getProjectState(project);
                    if (state != null) {
                        for (IProject library : state.getFullLibraryProjects()) {
                            allProjects.put(library, library);
                        }
                    }
                }
                for (IProject project : allProjects.keySet()) {
                    result.add(project);
                }

                return result;
            }
        }

        return resources;
    }
}
