/*
 *  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.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import org.apache.ivy.Ivy;
import org.apache.ivy.core.cache.ResolutionCacheManager;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleId;
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.settings.IvySettings;
import org.apache.ivy.util.Message;
import org.apache.ivy.util.filter.Filter;
import org.apache.ivy.util.filter.FilterHelper;
import org.apache.tools.ant.BuildException;

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

/**
 * Base class for tasks needing to be performed after a resolve.
 */
public abstract class IvyPostResolveTask extends IvyTask {
    private String conf;

    private boolean haltOnFailure = true;

    private boolean transitive = true;

    private boolean inline = false;

    private String organisation;

    private String branch = null;

    private String module;

    private String revision = "latest.integration";

    private String resolveId;

    private String type;

    private File file;

    private Filter<Artifact> artifactFilter = null;

    private boolean useOrigin = false;

    private Boolean keep = null;

    private boolean refresh = false;

    private String resolveMode = null;

    private String log = ResolveOptions.LOG_DEFAULT;

    private boolean changing = false;

    private IvyResolve resolve = new IvyResolve();

    public boolean isUseOrigin() {
        return useOrigin;
    }

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

    public String getLog() {
        return log;
    }

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

    public IvyDependency createDependency() {
        return resolve.createDependency();
    }

    public IvyExclude createExclude() {
        return resolve.createExclude();
    }

    public IvyOverride createOverride() {
      return resolve.createOverride();
    }

    public IvyConflict createConflict() {
        return resolve.createConflict();
    }

    protected void prepareAndCheck() {
        Ivy ivy = getIvyInstance();
        IvySettings settings = ivy.getSettings();

        boolean orgAndModSetManually = organisation != null && module != null;

        organisation = getProperty(organisation, settings, "ivy.organisation");
        module = getProperty(module, settings, "ivy.module");

        if (file == null) {
            String fileName = getProperty(settings, "ivy.resolved.file", resolveId);
            if (fileName != null) {
                file = getProject().resolveFile(fileName);
            }
        }

        if (isInline()) {
            if (conf == null) {
                conf = "*";
            }
            if (organisation == null) {
                throw new BuildException(
                        "no organisation provided for ivy cache task in inline mode: "
                                + "It can either be set explicitly via the attribute 'organisation' "
                                + "or via 'ivy.organisation' property");
            }
            if (module == null) {
                throw new BuildException(
                        "no module name provided for ivy cache task in inline mode: "
                                + "It can either be set explicitly via the attribute 'module' "
                                + "or via 'ivy.module' property");
            }
            String[] toResolve = getConfsToResolve(getOrganisation(), getModule() + "-caller",
                conf, true);
            // When we make an inline resolution, we can not resolve private confs.
            for (int i = 0; i < toResolve.length; i++) {
                if ("*".equals(toResolve[i])) {
                    toResolve[i] = "*(public)";
                }
            }
            if (toResolve.length > 0) {
                Message.verbose(String.format("using inline mode to resolve %s %s %s (%s)",
                        getOrganisation(), getModule(), getRevision(), joinArray(toResolve, ", ")));
                IvyResolve resolve = setupResolve(isHaltonfailure(), isUseOrigin());
                resolve.setOrganisation(getOrganisation());
                resolve.setModule(getModule());
                resolve.setBranch(getBranch());
                resolve.setRevision(getRevision());
                resolve.setInline(true);
                resolve.setChanging(isChanging());
                resolve.setConf(conf);
                resolve.setResolveId(resolveId);
                resolve.setTransitive(isTransitive());
                resolve.execute();
            } else {
                Message.verbose(String.format("inline resolve already done for %s %s %s (%s)",
                        getOrganisation(), getModule(), getRevision(), conf));
            }
            if ("*".equals(conf)) {
                conf = joinArray(
                    getResolvedConfigurations(getOrganisation(), getModule() + "-caller", true),
                    ", ");
            }
        } else {
            Message.debug("using standard ensure resolved");

            // if the organization and module has been manually specified, we'll reuse the resolved
            // data from another build (there is no way to know which configurations were resolved
            // there (TODO: maybe we can check which reports exist and extract the configurations
            // from these report names?)
            if (!orgAndModSetManually) {
                ensureResolved(settings);
            }

            conf = getProperty(conf, settings, "ivy.resolved.configurations");
            if ("*".equals(conf)) {
                conf = getProperty(settings, "ivy.resolved.configurations");
                if (conf == null) {
                    throw new BuildException("bad conf provided for ivy cache task: "
                            + "'*' can only be used with a prior call to <resolve/>");
                }
            }
        }
        organisation = getProperty(organisation, settings, "ivy.organisation");
        module = getProperty(module, settings, "ivy.module");
        if (organisation == null) {
            throw new BuildException("no organisation provided for ivy cache task: "
                    + "It can either be set explicitly via the attribute 'organisation' "
                    + "or via 'ivy.organisation' property or a prior call to <resolve/>");
        }
        if (module == null) {
            throw new BuildException("no module name provided for ivy cache task: "
                    + "It can either be set explicitly via the attribute 'module' "
                    + "or via 'ivy.module' property or a prior call to <resolve/>");
        }
        if (conf == null) {
            throw new BuildException("no conf provided for ivy cache task: "
                    + "It can either be set explicitly via the attribute 'conf' or "
                    + "via 'ivy.resolved.configurations' property or a prior call to <resolve/>");
        }

        artifactFilter = FilterHelper.getArtifactTypeFilter(type);
    }

    protected void ensureResolved(IvySettings settings) {
        String requestedConfigs = getProperty(getConf(), settings, "ivy.resolved.configurations");

        String[] confs = (getResolveId() == null)
                ? getConfsToResolve(getOrganisation(), getModule(), requestedConfigs, false)
                : getConfsToResolve(getResolveId(), requestedConfigs);

        if (confs.length > 0) {
            IvyResolve resolve = setupResolve(isHaltonfailure(), isUseOrigin());
            resolve.setFile(getFile());
            resolve.setTransitive(isTransitive());
            resolve.setConf(joinArray(confs, ", "));
            resolve.setResolveId(getResolveId());
            resolve.execute();
        }
    }

    protected String[] getConfsToResolve(String org, String module, String conf, boolean strict) {
        ModuleDescriptor reference = getResolvedDescriptor(org, module, strict);
        String[] rconfs = getResolvedConfigurations(org, module, strict);
        return getConfsToResolve(reference, conf, rconfs);
    }

    protected String[] getConfsToResolve(String resolveId, String conf) {
        ModuleDescriptor reference = getResolvedDescriptor(resolveId, false);
        if (reference == null) {
            // assume the module has been resolved outside this build, resolve the required
            // configurations again
            // TODO: find a way to discover which confs were resolved by that previous resolve
            if (conf == null) {
                return new String[] {"*"};
            }
            return splitToArray(conf);
        }
        String[] rconfs = getProject().getReference("ivy.resolved.configurations.ref." + resolveId);
        return getConfsToResolve(reference, conf, rconfs);
    }

    private String[] getConfsToResolve(ModuleDescriptor reference, String conf, String[] rconfs) {
        Message.debug("calculating configurations to resolve");

        if (reference == null) {
            Message.debug("module not yet resolved, all confs still need to be resolved");
            if (conf == null) {
                return new String[] {"*"};
            }
            return splitToArray(conf);
        }

        if (conf == null) {
            Message.debug("module already resolved, no configuration to resolve");
            return new String[0];
        }

        String[] confs;
        if ("*".equals(conf)) {
            confs = reference.getConfigurationsNames();
        } else {
            confs = splitToArray(conf);
        }

        Set<String> rconfsSet = new HashSet<>();

        // for each resolved configuration, check if the report still exists
        ResolutionCacheManager cache = getSettings().getResolutionCacheManager();
        for (String resolvedConf : rconfs) {
            String resolveId = getResolveId();
            if (resolveId == null) {
                resolveId = ResolveOptions.getDefaultResolveId(reference);
            }
            File report = cache.getConfigurationResolveReportInCache(resolveId, resolvedConf);
            // if the report does not exist any longer, we have to recreate it...
            if (report.exists()) {
                rconfsSet.add(resolvedConf);
            }
        }

        Set<String> confsSet = new HashSet<>(Arrays.asList(confs));
        Message.debug("resolved configurations:   " + rconfsSet);
        Message.debug("asked configurations:      " + confsSet);
        confsSet.removeAll(rconfsSet);
        Message.debug("to resolve configurations: " + confsSet);
        return confsSet.toArray(new String[confsSet.size()]);
    }

    protected IvyResolve setupResolve(boolean haltOnFailure, boolean useOrigin) {
        Message.verbose("no resolved descriptor found: launching default resolve");
        resolve.setTaskName(getTaskName());
        resolve.setProject(getProject());
        resolve.setHaltonfailure(haltOnFailure);
        resolve.setUseOrigin(useOrigin);
        resolve.setValidate(doValidate(getSettings()));
        resolve.setKeep(isKeep());
        resolve.setRefresh(isRefresh());
        resolve.setLog(getLog());
        resolve.setSettingsRef(getSettingsRef());
        resolve.setResolveMode(getResolveMode());
        return resolve;
    }

    protected ModuleRevisionId getResolvedMrid() {
        return new ModuleRevisionId(getResolvedModuleId(),
                (getRevision() == null) ? Ivy.getWorkingRevision() : getRevision());
    }

    protected ModuleId getResolvedModuleId() {
        return isInline() ? new ModuleId(getOrganisation(), getModule() + "-caller")
                : new ModuleId(getOrganisation(), getModule());
    }

    protected ResolveReport getResolvedReport() {
        return getResolvedReport(getOrganisation(), isInline() ? getModule() + "-caller"
                : getModule(), resolveId);
    }

    public String getType() {
        return type;
    }

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

    public String getConf() {
        return conf;
    }

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

    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 String getBranch() {
        return branch;
    }

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

    public boolean isHaltonfailure() {
        return haltOnFailure;
    }

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

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

    public String getRevision() {
        return revision;
    }

    public void setRevision(String rev) {
        revision = rev;
    }

    public Filter<Artifact> getArtifactFilter() {
        return artifactFilter;
    }

    public boolean isTransitive() {
        return transitive;
    }

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

    public boolean isInline() {
        return inline;
    }

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

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

    public String getResolveId() {
        return resolveId;
    }

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

    public File getFile() {
        return file;
    }

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

    public boolean isKeep() {
        return this.keep == null ? !isInline() : this.keep;
    }

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

    public boolean isChanging() {
        return this.changing;
    }

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

    public boolean isRefresh() {
        return refresh;
    }

    public String getResolveMode() {
        return resolveMode;
    }

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