/*
 * 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.apache.maven.shared.release.transform.jdom2;

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

import org.apache.maven.model.Build;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.DependencyManagement;
import org.apache.maven.model.Model;
import org.apache.maven.model.Parent;
import org.apache.maven.model.Profile;
import org.apache.maven.model.Reporting;
import org.apache.maven.model.Scm;
import org.apache.maven.shared.release.phase.AbstractRewritePomsPhase;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.Text;

/**
 * JDOM2 implementation of poms PROJECT element
 *
 * @author Robert Scholte
 * @since 3.0
 */
public class JDomModel extends Model {
    private final Element project;

    private final JDomModelBase modelBase;

    /**
     * <p>Constructor for JDomModel.</p>
     *
     * @param document a {@link org.jdom2.Document} object
     */
    public JDomModel(Document document) {
        this(document.getRootElement());
    }

    /**
     * <p>Constructor for JDomModel.</p>
     *
     * @param project a {@link org.jdom2.Element} object
     */
    public JDomModel(Element project) {
        this.project = project;
        this.modelBase = new JDomModelBase(project);
    }

    @Override
    public Build getBuild() {
        return modelBase.getBuild();
    }

    @Override
    public List<Dependency> getDependencies() {
        return modelBase.getDependencies();
    }

    @Override
    public DependencyManagement getDependencyManagement() {
        return modelBase.getDependencyManagement();
    }

    @Override
    public Parent getParent() {
        Element elm = getParentElement();
        if (elm == null) {
            return null;
        } else {
            // this way scm setters change DOM tree immediately
            return new JDomParent(elm);
        }
    }

    private Element getParentElement() {
        return project.getChild("parent", project.getNamespace());
    }

    @Override
    public List<Profile> getProfiles() {
        Element profilesElm = project.getChild("profiles", project.getNamespace());
        if (profilesElm == null) {
            return Collections.emptyList();
        } else {
            List<Element> profileElms = profilesElm.getChildren("profile", project.getNamespace());

            List<Profile> profiles = new ArrayList<>(profileElms.size());

            for (Element profileElm : profileElms) {
                profiles.add(new JDomProfile(profileElm));
            }

            return profiles;
        }
    }

    @Override
    public Properties getProperties() {
        Element properties = project.getChild("properties", project.getNamespace());

        if (properties == null) {
            return null;
        } else {
            return new JDomProperties(properties);
        }
    }

    @Override
    public Reporting getReporting() {
        Element reporting = project.getChild("reporting", project.getNamespace());

        if (reporting == null) {
            return null;
        } else {
            return new JDomReporting(reporting);
        }
    }

    @Override
    public void setScm(Scm scm) {
        if (scm == null) {
            JDomUtils.rewriteElement("scm", null, project, project.getNamespace());
        } else {
            Element scmRoot = new Element("scm");
            scmRoot.addContent("\n  ");

            // Write current values to JDOM2 tree
            Scm jdomScm = new JDomScm(scmRoot);
            jdomScm.setConnection(scm.getConnection());
            jdomScm.setDeveloperConnection(scm.getDeveloperConnection());
            jdomScm.setTag(scm.getTag());
            jdomScm.setUrl(scm.getUrl());

            project.addContent("\n  ").addContent(scmRoot).addContent("\n");
        }
    }

    @Override
    public Scm getScm() {
        Element elm = project.getChild("scm", project.getNamespace());
        if (elm == null) {
            return null;
        } else {
            // this way scm setters change DOM tree immediately
            return new JDomScm(elm);
        }
    }

    @Override
    public void setVersion(String version) {
        Element versionElement = project.getChild("version", project.getNamespace());

        String parentVersion;
        Element parent = getParentElement();
        if (parent != null) {
            parentVersion = parent.getChildTextTrim("version", project.getNamespace());
        } else {
            parentVersion = null;
        }

        if (versionElement == null) {
            // never add version when parent references CI friendly property
            if (!(parentVersion != null && AbstractRewritePomsPhase.isCiFriendlyVersion(parentVersion))
                    && !version.equals(parentVersion)) {
                // we will add this after artifactId, since it was missing but different from the inherited version
                Element artifactIdElement = project.getChild("artifactId", project.getNamespace());
                int index = project.indexOf(artifactIdElement);

                versionElement = new Element("version", project.getNamespace());
                versionElement.setText(version);
                project.addContent(index + 1, new Text("\n  "));
                project.addContent(index + 2, versionElement);
            }
        } else {
            if (AbstractRewritePomsPhase.isCiFriendlyVersion(versionElement.getTextNormalize())) {
                // try to rewrite property if CI friendly expression is used
                String ciFriendlyPropertyName =
                        AbstractRewritePomsPhase.extractPropertyFromExpression(versionElement.getTextNormalize());
                Properties properties = getProperties();
                if (properties != null) {
                    properties.setProperty(ciFriendlyPropertyName, version);
                }
            } else {
                JDomUtils.rewriteValue(versionElement, version);
            }
        }
    }
}
