/*
 *  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
 *
 *      https://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.ivy.ant;

import java.io.File;
import java.net.MalformedURLException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.ivy.Ivy;
import org.apache.ivy.core.LogOptions;
import org.apache.ivy.core.module.descriptor.DefaultExcludeRule;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ExtendsDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ResolveReport;
import org.apache.ivy.core.resolve.ResolveOptions;
import org.apache.ivy.core.resolve.ResolveProcessException;
import org.apache.ivy.core.settings.IvySettings;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.filter.FilterHelper;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;

import static org.apache.ivy.util.StringUtils.splitToArray;

/**
 * This task allow to call the Ivy dependency resolution from ant.
 */
public class IvyResolve extends IvyTask {
    private File file = null;

    private String conf = null;

    private String organisation = null;

    private String module = null;

    private String branch = null;

    private String revision = null;

    private String pubdate = null;

    private boolean inline = false;

    private boolean haltOnFailure = true;

    private boolean showProgress = true;

    private boolean useCacheOnly = false;

    private String type = null;

    private boolean transitive = true;

    private boolean refresh = false;

    private boolean changing = false;

    private Boolean keep = null;

    private String failureProperty = null;

    private boolean useOrigin = false;

    private String resolveMode = null;

    private String resolveId = null;

    private String log = ResolveOptions.LOG_DEFAULT;

    private boolean checkIfChanged = true; // for backward compatibility

    private List<IvyDependency> dependencies = new ArrayList<>();

    private List<IvyExclude> excludes = new ArrayList<>();

    private List<IvyOverride> overrides = new ArrayList<>();

    private List<IvyConflict> conflicts = new ArrayList<>();

    public boolean isUseOrigin() {
        return useOrigin;
    }

    public void setUseOrigin(boolean useOrigin) {
        this.useOrigin = useOrigin;
    }

    public String getDate() {
        return pubdate;
    }

    public void setDate(String pubdate) {
        this.pubdate = pubdate;
    }

    public String getRevision() {
        return revision;
    }

    public void setRevision(String revision) {
        this.revision = revision;
    }

    public String getBranch() {
        return branch;
    }

    public void setBranch(String branch) {
        this.branch = branch;
    }

    public void setCache(File cache) {
        cacheAttributeNotSupported();
    }

    public String getConf() {
        return conf;
    }

    public void setConf(String conf) {
        this.conf = conf;
    }

    public File getFile() {
        return file;
    }

    public void setFile(File file) {
        this.file = file;
    }

    public boolean isHaltonfailure() {
        return haltOnFailure;
    }

    public void setHaltonfailure(boolean haltOnFailure) {
        this.haltOnFailure = haltOnFailure;
    }

    public void setShowprogress(boolean show) {
        this.showProgress = show;
    }

    public boolean isUseCacheOnly() {
        return useCacheOnly;
    }

    public void setUseCacheOnly(boolean useCacheOnly) {
        this.useCacheOnly = useCacheOnly;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public boolean isRefresh() {
        return refresh;
    }

    public void setRefresh(boolean refresh) {
        this.refresh = refresh;
    }

    public String getLog() {
        return log;
    }

    public void setLog(String log) {
        this.log = log;
    }

    /**
     * @param failureProperty String
     * @deprecated Use {@link #setFailureProperty(String)} instead
     */
    @Deprecated
    public void setFailurePropery(String failureProperty) {
        log("The 'failurepropery' attribute is deprecated. "
                + "Please use the 'failureproperty' attribute instead", Project.MSG_WARN);
        setFailureProperty(failureProperty);
    }

    public void setFailureProperty(String failureProperty) {
        this.failureProperty = failureProperty;
    }

    public String getFailureProperty() {
        return failureProperty;
    }

    public IvyDependency createDependency() {
        IvyDependency dep = new IvyDependency();
        dependencies.add(dep);
        return dep;
    }

    public IvyExclude createExclude() {
        IvyExclude ex = new IvyExclude();
        excludes.add(ex);
        return ex;
    }

    public IvyOverride createOverride() {
        IvyOverride o = new IvyOverride();
        overrides.add(o);
        return o;
    }

    public IvyConflict createConflict() {
        IvyConflict c = new IvyConflict();
        conflicts.add(c);
        return c;
    }

    @Override
    protected void prepareTask() {
        super.prepareTask();
        Message.setShowProgress(showProgress);
    }

    @Override
    public void doExecute() throws BuildException {
        Ivy ivy = getIvyInstance();
        IvySettings settings = ivy.getSettings();
        try {
            conf = getProperty(conf, settings, "ivy.configurations");
            type = getProperty(type, settings, "ivy.resolve.default.type.filter");
            String[] confs = splitToArray(conf);

            boolean childs = !dependencies.isEmpty() || !excludes.isEmpty() || !overrides.isEmpty()
                || !conflicts.isEmpty();

            ResolveReport report;
            if (childs) {
                if (isInline()) {
                    throw new BuildException("the inline mode is incompatible with child elements");
                }
                if (organisation != null) {
                    throw new BuildException("'organisation' is not allowed with child elements");
                }
                if (module != null) {
                    throw new BuildException("'module' is not allowed with child elements");
                }
                if (file != null) {
                    throw new BuildException("'file' not allowed with child elements");
                }
                if (!getAllowedLogOptions().contains(log)) {
                    throw new BuildException("invalid option for 'log': " + log
                            + ". Available options are " + getAllowedLogOptions());
                }

                ModuleRevisionId mrid = ModuleRevisionId.newInstance("", "",
                    Ivy.getWorkingRevision());
                DefaultModuleDescriptor md = DefaultModuleDescriptor.newBasicInstance(mrid, null);

                for (IvyDependency dep : dependencies) {
                    DependencyDescriptor dd = dep.asDependencyDescriptor(md, "default", settings);
                    md.addDependency(dd);
                }

                for (IvyExclude exclude : excludes) {
                    DefaultExcludeRule rule = exclude.asRule(settings);
                    rule.addConfiguration("default");
                    md.addExcludeRule(rule);
                }

                for (IvyOverride override : overrides) {
                  override.addOverride(md, settings);
                }

                for (IvyConflict conflict : conflicts) {
                    conflict.addConflict(md, settings);
                }

                report = ivy
                        .resolve(md, getResolveOptions(ivy, new String[] {"default"}, settings));
            } else if (isInline()) {
                if (organisation == null) {
                    throw new BuildException("'organisation' is required when using inline mode");
                }
                if (module == null) {
                    throw new BuildException("'module' is required when using inline mode");
                }
                if (file != null) {
                    throw new BuildException("'file' not allowed when using inline mode");
                }
                if (!getAllowedLogOptions().contains(log)) {
                    throw new BuildException("invalid option for 'log': " + log
                            + ". Available options are " + getAllowedLogOptions());
                }
                for (int i = 0; i < confs.length; i++) {
                    if ("*".equals(confs[i])) {
                        confs[i] = "*(public)";
                    }
                }
                if (revision == null) {
                    revision = "latest.integration";
                }
                report = ivy.resolve(
                    ModuleRevisionId.newInstance(organisation, module, branch, revision),
                    getResolveOptions(ivy, confs, settings), changing);

            } else {
                if (organisation != null) {
                    throw new BuildException(
                            "'organisation' not allowed when not using 'org' attribute");
                }
                if (module != null) {
                    throw new BuildException("'module' not allowed when not using 'org' attribute");
                }
                if (file == null) {
                    file = getProject().resolveFile(getProperty(settings, "ivy.dep.file"));
                }
                report = ivy.resolve(file.toURI().toURL(), getResolveOptions(ivy, confs, settings));
            }
            if (report.hasError()) {
                if (failureProperty != null) {
                    getProject().setProperty(failureProperty, "true");
                }
                if (isHaltonfailure()) {
                    throw new BuildException("resolve failed - see output for details");
                }
            }
            setResolved(report, resolveId, isKeep());
            confs = report.getConfigurations();

            if (isKeep()) {
                ModuleDescriptor md = report.getModuleDescriptor();
                // put resolved infos in ant properties and ivy variables
                // putting them in ivy variables is important to be able to change from one resolve
                // call to the other
                String mdOrg = md.getModuleRevisionId().getOrganisation();
                String mdName = md.getModuleRevisionId().getName();
                String mdRev = md.getResolvedModuleRevisionId().getRevision();
                getProject().setProperty("ivy.organisation", mdOrg);
                settings.setVariable("ivy.organisation", mdOrg);
                getProject().setProperty("ivy.module", mdName);
                settings.setVariable("ivy.module", mdName);
                getProject().setProperty("ivy.revision", mdRev);
                settings.setVariable("ivy.revision", mdRev);
                List<ExtendsDescriptor> parents = Arrays.asList(md.getInheritedDescriptors());
                for (ExtendsDescriptor parent : parents) {
                    int i = parents.indexOf(parent);
                    String parentOrg = parent.getResolvedParentRevisionId().getOrganisation();
                    String parentModule = parent.getResolvedParentRevisionId().getName();
                    String parentRevision = parent.getResolvedParentRevisionId().getRevision();
                    String parentBranch = parent.getResolvedParentRevisionId().getBranch();
                    getProject().setProperty("ivy.parent[" + i + "].organisation", parentOrg);
                    settings.setVariable("ivy.parent[" + i + "].organisation", parentOrg);
                    getProject().setProperty("ivy.parent[" + i + "].module", parentModule);
                    settings.setVariable("ivy.parent[" + i + "].module", parentModule);
                    getProject().setProperty("ivy.parent[" + i + "].revision", parentRevision);
                    settings.setVariable("ivy.parent[" + i + "].revision", parentRevision);
                    if (parentBranch != null) {
                        getProject().setProperty("ivy.parent[" + i + "].branch", parentBranch);
                        settings.setVariable("ivy.parent[" + i + "].branch", parentBranch);
                    }
                }
                getProject().setProperty("ivy.parents.count",
                    String.valueOf(md.getInheritedDescriptors().length));
                settings.setVariable("ivy.parents.count",
                    String.valueOf(md.getInheritedDescriptors().length));

                Boolean hasChanged = null;
                if (getCheckIfChanged()) {
                    hasChanged = report.hasChanged();
                    getProject().setProperty("ivy.deps.changed", hasChanged.toString());
                    settings.setVariable("ivy.deps.changed", hasChanged.toString());
                }
                getProject().setProperty("ivy.resolved.configurations", mergeConfs(confs));
                settings.setVariable("ivy.resolved.configurations", mergeConfs(confs));
                if (file != null) {
                    getProject().setProperty("ivy.resolved.file", file.getAbsolutePath());
                    settings.setVariable("ivy.resolved.file", file.getAbsolutePath());
                }
                if (resolveId != null) {
                    getProject().setProperty("ivy.organisation." + resolveId, mdOrg);
                    settings.setVariable("ivy.organisation." + resolveId, mdOrg);
                    getProject().setProperty("ivy.module." + resolveId, mdName);
                    settings.setVariable("ivy.module." + resolveId, mdName);
                    getProject().setProperty("ivy.revision." + resolveId, mdRev);
                    settings.setVariable("ivy.revision." + resolveId, mdRev);
                    if (getCheckIfChanged()) {
                        // hasChanged has already been set earlier
                        getProject().setProperty("ivy.deps.changed." + resolveId,
                            hasChanged.toString());
                        settings.setVariable("ivy.deps.changed." + resolveId, hasChanged.toString());
                    }
                    getProject().setProperty("ivy.resolved.configurations." + resolveId,
                        mergeConfs(confs));
                    settings.setVariable("ivy.resolved.configurations." + resolveId,
                        mergeConfs(confs));
                    if (file != null) {
                        getProject().setProperty("ivy.resolved.file." + resolveId,
                            file.getAbsolutePath());
                        settings.setVariable("ivy.resolved.file." + resolveId,
                            file.getAbsolutePath());
                    }
                }
            }
        } catch (MalformedURLException e) {
            throw new BuildException("unable to convert given ivy file to url: " + file + ": " + e,
                    e);
        } catch (ParseException e) {
            log(e.getMessage(), Project.MSG_ERR);
            throw new BuildException("syntax errors in ivy file: " + e, e);
        } catch (ResolveProcessException e) {
            throw new BuildException("impossible to resolve dependencies:\n\t" + e.getMessage(), e);
        } catch (Exception e) {
            throw new BuildException("impossible to resolve dependencies:\n\t" + e, e);
        }
    }

    protected Collection<String> getAllowedLogOptions() {
        return Arrays.asList(LogOptions.LOG_DEFAULT, LogOptions.LOG_DOWNLOAD_ONLY,
            LogOptions.LOG_QUIET);
    }

    private ResolveOptions getResolveOptions(Ivy ivy, String[] confs, IvySettings settings) {
        if (useOrigin) {
            settings.useDeprecatedUseOrigin();
        }
        return ((ResolveOptions) new ResolveOptions().setLog(log)).setConfs(confs)
                .setValidate(doValidate(settings))
                .setArtifactFilter(FilterHelper.getArtifactTypeFilter(type)).setRevision(revision)
                .setDate(getPubDate(pubdate, null)).setUseCacheOnly(useCacheOnly)
                .setRefresh(refresh).setTransitive(transitive).setResolveMode(resolveMode)
                .setResolveId(resolveId).setCheckIfChanged(checkIfChanged);
    }

    public String getModule() {
        return module;
    }

    public void setModule(String module) {
        this.module = module;
    }

    public String getOrganisation() {
        return organisation;
    }

    public void setOrganisation(String organisation) {
        this.organisation = organisation;
    }

    public boolean isTransitive() {
        return transitive;
    }

    public void setTransitive(boolean transitive) {
        this.transitive = transitive;
    }

    public boolean isChanging() {
        return changing;
    }

    public void setChanging(boolean changing) {
        this.changing = changing;
    }

    public boolean isKeep() {
        return (keep == null) ? organisation == null : keep;
    }

    public void setKeep(boolean keep) {
        this.keep = keep;
    }

    public boolean isInline() {
        return inline;
    }

    public void setInline(boolean inline) {
        this.inline = inline;
    }

    public String getResolveId() {
        return resolveId;
    }

    public void setResolveId(String resolveId) {
        this.resolveId = resolveId;
    }

    public String getResolveMode() {
        return resolveMode;
    }

    public void setResolveMode(String resolveMode) {
        this.resolveMode = resolveMode;
    }

    public boolean getCheckIfChanged() {
        return checkIfChanged;
    }

    public void setCheckIfChanged(boolean checkIfChanged) {
        this.checkIfChanged = checkIfChanged;
    }
}
