/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
 *
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
 * Other names may be trademarks of their respective owners.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 *
 * Contributor(s):
 *
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
 */
package org.netbeans.modules.maven.apisupport;

import java.util.ArrayList;
import java.util.List;
import org.netbeans.api.project.Project;
import org.netbeans.modules.apisupport.project.spi.NbRefactoringContext;
import org.netbeans.modules.apisupport.project.spi.NbRefactoringProvider;
import org.netbeans.modules.maven.api.NbMavenProject;
import org.netbeans.modules.maven.model.ModelOperation;
import org.netbeans.modules.maven.model.Utilities;
import org.netbeans.modules.maven.model.pom.Build;
import org.netbeans.modules.maven.model.pom.Configuration;
import org.netbeans.modules.maven.model.pom.POMExtensibilityElement;
import org.netbeans.modules.maven.model.pom.POMModel;
import org.netbeans.modules.maven.model.pom.POMModelFactory;
import org.netbeans.modules.maven.model.pom.Plugin;
import org.netbeans.modules.xml.xam.ModelSource;
import org.netbeans.spi.project.ProjectServiceProvider;
import org.openide.filesystems.FileObject;
import org.openide.util.NbBundle;

/**
 *
 * @author mkozeny
 */
@ProjectServiceProvider(service = NbRefactoringProvider.class, projectType = "org-netbeans-modules-maven/" + NbMavenProject.TYPE_NBM)
public class MavenRefactoringProviderImpl implements NbRefactoringProvider {

    private Project project;

    public MavenRefactoringProviderImpl(Project project) {
        this.project = project;
    }

    @Override
    public List<ProjectFileRefactoring> getProjectFilesRefactoring(final NbRefactoringContext context) {
        List<ProjectFileRefactoring> result = new ArrayList<ProjectFileRefactoring>();

        FileObject fo = project.getProjectDirectory();
        final FileObject pomFileObject = fo.getFileObject("pom.xml");
        ModelSource source = Utilities.createModelSource(pomFileObject);

        final POMModel pomModel = POMModelFactory.getDefault().getModel(source);
        Build build = pomModel.getProject().getBuild();

        if (build != null) {
            Plugin nbmPlugin = build.findPluginById(MavenNbModuleImpl.GROUPID_MOJO, MavenNbModuleImpl.NBM_PLUGIN);
            if (nbmPlugin != null) {
                Configuration config = nbmPlugin.getConfiguration();
                if (config != null) {
                    List<POMExtensibilityElement> configElems = config.getConfigurationElements();
                    POMExtensibilityElement packages = null;
                    for (POMExtensibilityElement elem : configElems) {
                        if ("publicPackages".equals(elem.getQName().getLocalPart())) {
                            packages = elem;
                            break;
                        }
                    }

                    if (packages != null) {
                        List<POMExtensibilityElement> elems = packages.getAnyElements();
                        for (final POMExtensibilityElement elem : elems) {
                            if (elem.getElementText().equals(context.getOldPackagePath())) {
                                result.add(new ProjectFileRefactoring(pomFileObject) {

                                    @Override
                                    public void performChange() {
                                        ModelOperation<POMModel> operation = new ModelOperation<POMModel>() {

                                            @Override
                                            public void performOperation(POMModel model) {
                                                Build build = model.getProject().getBuild();

                                                if (build != null) {
                                                    Plugin nbmPlugin = build.findPluginById(MavenNbModuleImpl.GROUPID_MOJO, MavenNbModuleImpl.NBM_PLUGIN);
                                                    if (nbmPlugin != null) {
                                                        Configuration config = nbmPlugin.getConfiguration();
                                                        if (config != null) {
                                                            List<POMExtensibilityElement> configElems = config.getConfigurationElements();
                                                            POMExtensibilityElement packages = null;
                                                            for (POMExtensibilityElement elem : configElems) {
                                                                if ("publicPackages".equals(elem.getQName().getLocalPart())) {
                                                                    packages = elem;
                                                                    break;
                                                                }
                                                            }

                                                            if (packages != null) {
                                                                List<POMExtensibilityElement> elems = packages.getAnyElements();
                                                                for (final POMExtensibilityElement elem : elems) {
                                                                    if (elem.getElementText().equals(context.getOldPackagePath())) {
                                                                        elem.setElementText(context.getNewPackagePath());

                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        };
                                        List<ModelOperation<POMModel>> operations = new ArrayList<ModelOperation<POMModel>>();
                                        operations.add(operation);
                                        Utilities.performPOMModelOperations(pomFileObject, operations);
                                    }

                                    @Override

                                    public String getDisplayText() {
                                        return NbBundle.getMessage(MavenRefactoringProviderImpl.class, "TXT_ProjectXmlFileElementValueRename", "publicPackage", context.getOldPackagePath());
                                    }
                                });
                            }
                        }
                    }
                }
            }
        }
        return result;
    }

}
