/*
 * Copyright (C) 2007 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.build.builders;

import com.android.annotations.NonNull;
import com.android.annotations.Nullable;
import com.android.ide.common.sdk.LoadStatus;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.build.BuildHelper;
import com.android.ide.eclipse.adt.internal.build.Messages;
import com.android.ide.eclipse.adt.internal.preferences.AdtPrefs.BuildVerbosity;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler;
import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener;
import com.android.ide.eclipse.adt.internal.sdk.ProjectState;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.io.IFileWrapper;
import com.android.io.IAbstractFile;
import com.android.io.StreamException;
import com.android.sdklib.BuildToolInfo;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.repository.FullRevision;

import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jdt.core.IJavaProject;
import org.xml.sax.SAXException;

import java.util.ArrayList;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

/**
 * Base builder for XML files. This class allows for basic XML parsing with
 * error checking and marking the files for errors/warnings.
 */
public abstract class BaseBuilder extends IncrementalProjectBuilder {

    protected static final boolean DEBUG_LOG = "1".equals(              //$NON-NLS-1$
            System.getenv("ANDROID_BUILD_DEBUG"));                      //$NON-NLS-1$

    /** SAX Parser factory. */
    private SAXParserFactory mParserFactory;

    /**
     * The build tool to use to build. This is guaranteed to be non null after a call to
     * {@link #abortOnBadSetup(IJavaProject, ProjectState)} since this will throw if it can't be
     * queried.
     */
    protected BuildToolInfo mBuildToolInfo;

    /**
     * Base Resource Delta Visitor to handle XML error
     */
    protected static class BaseDeltaVisitor implements XmlErrorListener {

        /** The Xml builder used to validate XML correctness. */
        protected BaseBuilder mBuilder;

        /**
         * XML error flag. if true, we keep parsing the ResourceDelta but the
         * compilation will not happen (we're putting markers)
         */
        public boolean mXmlError = false;

        public BaseDeltaVisitor(BaseBuilder builder) {
            mBuilder = builder;
        }

        /**
         * Finds a matching Source folder for the current path. This checks if the current path
         * leads to, or is a source folder.
         * @param sourceFolders The list of source folders
         * @param pathSegments The segments of the current path
         * @return The segments of the source folder, or null if no match was found
         */
        protected static String[] findMatchingSourceFolder(ArrayList<IPath> sourceFolders,
                String[] pathSegments) {

            for (IPath p : sourceFolders) {
                // check if we are inside one of those source class path

                // get the segments
                String[] srcSegments = p.segments();

                // compare segments. We want the path of the resource
                // we're visiting to be
                boolean valid = true;
                int segmentCount = pathSegments.length;

                for (int i = 0 ; i < segmentCount; i++) {
                    String s1 = pathSegments[i];
                    String s2 = srcSegments[i];

                    if (s1.equalsIgnoreCase(s2) == false) {
                        valid = false;
                        break;
                    }
                }

                if (valid) {
                    // this folder, or one of this children is a source
                    // folder!
                    // we return its segments
                    return srcSegments;
                }
            }

            return null;
        }

        /**
         * Sent when an XML error is detected.
         * @see XmlErrorListener
         */
        @Override
        public void errorFound() {
            mXmlError = true;
        }
    }

    protected static class AbortBuildException extends Exception {
        private static final long serialVersionUID = 1L;
    }

    public BaseBuilder() {
        super();
        mParserFactory = SAXParserFactory.newInstance();

        // FIXME when the compiled XML support for namespace is in, set this to true.
        mParserFactory.setNamespaceAware(false);
    }

    /**
     * Checks an Xml file for validity. Errors/warnings will be marked on the
     * file
     * @param resource the resource to check
     * @param visitor a valid resource delta visitor
     */
    protected final void checkXML(IResource resource, BaseDeltaVisitor visitor) {

        // first make sure this is an xml file
        if (resource instanceof IFile) {
            IFile file = (IFile)resource;

            // remove previous markers
            removeMarkersFromResource(file, AdtConstants.MARKER_XML);

            // create  the error handler
            XmlErrorHandler reporter = new XmlErrorHandler(file, visitor);
            try {
                // parse
                getParser().parse(file.getContents(), reporter);
            } catch (Exception e1) {
            }
        }
    }

    /**
     * Returns the SAXParserFactory, instantiating it first if it's not already
     * created.
     * @return the SAXParserFactory object
     * @throws ParserConfigurationException
     * @throws SAXException
     */
    protected final SAXParser getParser() throws ParserConfigurationException,
            SAXException {
        return mParserFactory.newSAXParser();
    }

    /**
     * Adds a marker to the current project.  This methods catches thrown {@link CoreException},
     * and returns null instead.
     *
     * @param markerId The id of the marker to add.
     * @param message the message associated with the mark
     * @param severity the severity of the marker.
     * @return the marker that was created (or null if failure)
     * @see IMarker
     */
    protected final IMarker markProject(String markerId, String message, int severity) {
        return BaseProjectHelper.markResource(getProject(), markerId, message, severity);
    }

    /**
     * Removes markers from a resource and only the resource (not its children).
     * @param file The file from which to delete the markers.
     * @param markerId The id of the markers to remove. If null, all marker of
     * type <code>IMarker.PROBLEM</code> will be removed.
     */
    public final void removeMarkersFromResource(IResource resource, String markerId) {
        try {
            if (resource.exists()) {
                resource.deleteMarkers(markerId, true, IResource.DEPTH_ZERO);
            }
        } catch (CoreException ce) {
            String msg = String.format(Messages.Marker_Delete_Error, markerId, resource.toString());
            AdtPlugin.printErrorToConsole(getProject(), msg);
        }
    }

    /**
     * Removes markers from a container and its children.
     * @param folder The container from which to delete the markers.
     * @param markerId The id of the markers to remove. If null, all marker of
     * type <code>IMarker.PROBLEM</code> will be removed.
     */
    protected final void removeMarkersFromContainer(IContainer folder, String markerId) {
        try {
            if (folder.exists()) {
                folder.deleteMarkers(markerId, true, IResource.DEPTH_INFINITE);
            }
        } catch (CoreException ce) {
            String msg = String.format(Messages.Marker_Delete_Error, markerId, folder.toString());
            AdtPlugin.printErrorToConsole(getProject(), msg);
        }
    }

    /**
     * Get the stderr output of a process and return when the process is done.
     * @param process The process to get the ouput from
     * @param stdErr The array to store the stderr output
     * @return the process return code.
     * @throws InterruptedException
     */
    protected final int grabProcessOutput(final Process process,
            final ArrayList<String> stdErr) throws InterruptedException {
        return BuildHelper.grabProcessOutput(getProject(), process, stdErr);
    }



    /**
     * Saves a String property into the persistent storage of the project.
     * @param propertyName the name of the property. The id of the plugin is added to this string.
     * @param value the value to save
     * @return true if the save succeeded.
     */
    protected boolean saveProjectStringProperty(String propertyName, String value) {
        IProject project = getProject();
        return ProjectHelper.saveStringProperty(project, propertyName, value);
    }


    /**
     * Loads a String property from the persistent storage of the project.
     * @param propertyName the name of the property. The id of the plugin is added to this string.
     * @return the property value or null if it was not found.
     */
    protected String loadProjectStringProperty(String propertyName) {
        IProject project = getProject();
        return ProjectHelper.loadStringProperty(project, propertyName);
    }

    /**
     * Saves a property into the persistent storage of the project.
     * @param propertyName the name of the property. The id of the plugin is added to this string.
     * @param value the value to save
     * @return true if the save succeeded.
     */
    protected boolean saveProjectBooleanProperty(String propertyName, boolean value) {
        IProject project = getProject();
        return ProjectHelper.saveStringProperty(project, propertyName, Boolean.toString(value));
    }

    /**
     * Loads a boolean property from the persistent storage of the project.
     * @param propertyName the name of the property. The id of the plugin is added to this string.
     * @param defaultValue The default value to return if the property was not found.
     * @return the property value or the default value if the property was not found.
     */
    protected boolean loadProjectBooleanProperty(String propertyName, boolean defaultValue) {
        IProject project = getProject();
        return ProjectHelper.loadBooleanProperty(project, propertyName, defaultValue);
    }

    /**
     * Aborts the build if the SDK/project setups are broken. This does not
     * display any errors.
     *
     * @param javaProject The {@link IJavaProject} being compiled.
     * @param projectState the project state, optional. will be queried if null.
     * @throws CoreException
     */
    protected void abortOnBadSetup(@NonNull IJavaProject javaProject,
            @Nullable ProjectState projectState) throws AbortBuildException, CoreException {
        IProject iProject = javaProject.getProject();
        // check if we have finished loading the project target.
        Sdk sdk = Sdk.getCurrent();
        if (sdk == null) {
            throw new AbortBuildException();
        }

        if (projectState == null) {
            projectState = Sdk.getProjectState(javaProject.getProject());
        }

        // get the target for the project
        IAndroidTarget target = projectState.getTarget();

        if (target == null) {
            throw new AbortBuildException();
        }

        // check on the target data.
        if (sdk.checkAndLoadTargetData(target, javaProject) != LoadStatus.LOADED) {
            throw new AbortBuildException();
       }

        mBuildToolInfo = projectState.getBuildToolInfo();
        if (mBuildToolInfo == null) {
            mBuildToolInfo = sdk.getLatestBuildTool();

            if (mBuildToolInfo == null) {
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, iProject,
                        "No \"Build Tools\" package available; use SDK Manager to install one.");
                throw new AbortBuildException();
            } else {
                AdtPlugin.printBuildToConsole(BuildVerbosity.VERBOSE, iProject,
                        String.format("Using default Build Tools revision %s",
                                mBuildToolInfo.getRevision())
                        );
            }
        }

        // abort if there are TARGET or ADT type markers
        stopOnMarker(iProject, AdtConstants.MARKER_TARGET, IResource.DEPTH_ZERO,
                false /*checkSeverity*/);
        stopOnMarker(iProject, AdtConstants.MARKER_ADT, IResource.DEPTH_ZERO,
                false /*checkSeverity*/);
    }

    protected void stopOnMarker(IProject project, String markerType, int depth,
            boolean checkSeverity)
            throws AbortBuildException {
        try {
            IMarker[] markers = project.findMarkers(markerType, false /*includeSubtypes*/, depth);

            if (markers.length > 0) {
                if (checkSeverity == false) {
                    throw new AbortBuildException();
                } else {
                    for (IMarker marker : markers) {
                        int severity = marker.getAttribute(IMarker.SEVERITY, -1 /*defaultValue*/);
                        if (severity == IMarker.SEVERITY_ERROR) {
                            throw new AbortBuildException();
                        }
                    }
                }
            }
        } catch (CoreException e) {
            // don't stop, something's really screwed up and the build will break later with
            // a better error message.
        }
    }

    /**
     * Handles a {@link StreamException} by logging the info and marking the project.
     * This should generally be followed by exiting the build process.
     *
     * @param e the exception
     */
    protected void handleStreamException(StreamException e) {
        IAbstractFile file = e.getFile();

        String msg;

        IResource target = getProject();
        if (file instanceof IFileWrapper) {
            target = ((IFileWrapper) file).getIFile();

            if (e.getError() == StreamException.Error.OUTOFSYNC) {
                msg = "File is Out of sync";
            } else {
                msg = "Error reading file. Read log for details";
            }

        } else {
            if (e.getError() == StreamException.Error.OUTOFSYNC) {
                msg = String.format("Out of sync file: %s", file.getOsLocation());
            } else {
                msg = String.format("Error reading file %s. Read log for details",
                        file.getOsLocation());
            }
        }

        AdtPlugin.logAndPrintError(e, getProject().getName(), msg);
        BaseProjectHelper.markResource(target, AdtConstants.MARKER_ADT, msg,
                IMarker.SEVERITY_ERROR);
    }

    /**
     * Handles a generic {@link Throwable} by logging the info and marking the project.
     * This should generally be followed by exiting the build process.
     *
     * @param t the {@link Throwable}.
     * @param message the message to log and to associate with the marker.
     */
    protected void handleException(Throwable t, String message) {
        AdtPlugin.logAndPrintError(t, getProject().getName(), message);
        markProject(AdtConstants.MARKER_ADT, message, IMarker.SEVERITY_ERROR);
    }

    /**
     * Recursively delete all the derived resources from a root resource. The root resource is not
     * deleted.
     * @param rootResource the root resource
     * @param monitor a progress monitor.
     * @throws CoreException
     *
     */
    protected void removeDerivedResources(IResource rootResource, IProgressMonitor monitor)
            throws CoreException {
        removeDerivedResources(rootResource, false, monitor);
    }

    /**
     * delete a resource and its children. returns true if the root resource was deleted. All
     * sub-folders *will* be deleted if they were emptied (not if they started empty).
     * @param rootResource the root resource
     * @param deleteRoot whether to delete the root folder.
     * @param monitor a progress monitor.
     * @throws CoreException
     */
    private void removeDerivedResources(IResource rootResource, boolean deleteRoot,
            IProgressMonitor monitor) throws CoreException {
        if (rootResource.exists()) {
            // if it's a folder, delete derived member.
            if (rootResource.getType() == IResource.FOLDER) {
                IFolder folder = (IFolder)rootResource;
                IResource[] members = folder.members();
                boolean wasNotEmpty = members.length > 0;
                for (IResource member : members) {
                    removeDerivedResources(member, true /*deleteRoot*/, monitor);
                }

                // if the folder had content that is now all removed, delete the folder.
                if (deleteRoot && wasNotEmpty && folder.members().length == 0) {
                    rootResource.getLocation().toFile().delete();
                }
            }

            // if the root resource is derived, delete it.
            if (rootResource.isDerived()) {
                rootResource.getLocation().toFile().delete();
            }
        }
    }

    protected void launchJob(Job newJob) {
        newJob.setPriority(Job.BUILD);
        newJob.setRule(ResourcesPlugin.getWorkspace().getRoot());
        newJob.schedule();
    }
}
