/*
 *  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.ant.s3;

import java.io.File;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.Spliterators;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Supplier;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.PatternSet;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceCollection;
import org.apache.tools.ant.types.resources.Union;
import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
import org.apache.tools.ant.util.StringUtils;

import software.amazon.awssdk.services.s3.S3Client;

/**
 * {@link ResourceCollection} of {@link ObjectResource}s.
 */
public class ObjectResources extends S3DataType implements ResourceCollection {

    /**
     * Default delimiter.
     */
    public static final String DEFAULT_DELIMITER = "/";

    private static <T> Stream<T> sequentialStream(Iterator<T> iterator) {
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, 0), false);
    }

    private Supplier<S3Client> s3;
    private String bucket;
    private String delimiter = DEFAULT_DELIMITER;
    private Precision as = Precision.object;

    private final PatternSet patterns = new PatternSet();
    private final List<ResourceSelector> selectors = new ArrayList<>();

    private volatile boolean caseSensitive = true;

    private volatile Optional<ResourceCollection> resourceCache;
    private volatile boolean cache = true;
    private volatile boolean includePrefixes;

    /**
     * Create a new {@link ObjectResources} instance.
     *
     * @param project
     *            Ant {@link Project}
     */
    public ObjectResources(final Project project) {
        super(project);
        patterns.setProject(project);
        resetResourceCache();
    }

    /**
     * Add the nested {@link Client}.
     *
     * @param s3
     *            {@link Client}
     */
    public void addConfigured(final Client s3) {
        checkChildrenAllowed();

        Exceptions.raiseUnless(this.s3 == null, buildException(),
            () -> String.format("%s already specified", componentName(Client.class)));

        this.s3 = Objects.requireNonNull(s3);
        resetResourceCache();
    }

    /**
     * Set {@link Client} by reference.
     *
     * @param refid
     *            of {@link Client}
     */
    public void setClientRefid(final String refid) {
        checkAttributesAllowed();

        Exceptions.raiseIf(StringUtils.trimToNull(refid) == null, buildException(),
            "@clientrefid must not be null/empty/blank");

        addConfigured(getProject().<Client> getReference(refid));
    }

    /**
     * Add a configured {@link ResourceSelector}.
     *
     * @param selector
     *            to add
     */
    public void addConfigured(ResourceSelector selector) {
        checkChildrenAllowed();

        if (selector == null) {
            return;
        }
        selectors.add(selector);
        resetResourceCache();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Iterator<Resource> iterator() {
        if (isReference()) {
            getCheckedRef(ObjectResources.class).iterator();
        }
        if (resourceCache.isPresent()) {
            return resourceCache.get().iterator();
        }
        final S3Finder finder = new S3Finder(getProject(), s3(), require(getBucket(), "@bucket"), as,
            require(getDelimiter(), "@delimiter"), patterns, isCaseSensitive(), isIncludePrefixes());

        final Optional<Set<ObjectResource>> cacheSet;
        if (isCache()) {
            cacheSet = Optional.of(new LinkedHashSet<>());
        } else {
            cacheSet = Optional.empty();
        }
        final Iterator<Resource> result = new Iterator<Resource>() {
            Optional<ObjectResource> next = finder.get();

            @Override
            public Resource next() {
                try {
                    final ObjectResource e = next.orElseThrow(NoSuchElementException::new);
                    cacheSet.ifPresent(c -> c.add(e));
                    return e;
                } finally {
                    next = finder.get();
                    if (!next.isPresent()) {
                        cacheSet.ifPresent(c -> {
                            final Union u = new Union(getProject());
                            u.addAll(c);
                            resourceCache = Optional.of(u);
                        });
                    }
                }
            }

            @Override
            public boolean hasNext() {
                return next.isPresent();
            }
        };

        return selectors.isEmpty() ? result : sequentialStream(result).filter(this::isSelected).iterator();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int size() {
        if (isReference()) {
            return getCheckedRef(ObjectResources.class).size();
        }
        if (resourceCache.isPresent()) {
            return resourceCache.get().size();
        }
        if (patterns.hasPatterns(getProject()) || !selectors.isEmpty()) {
            final AtomicInteger result = new AtomicInteger();
            iterator().forEachRemaining(junk -> result.incrementAndGet());
            return result.intValue();
        }

        return new Counter(s3(), require(getBucket(), "@bucket")).getAsInt();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isFilesystemOnly() {
        return false;
    }

    /**
     * Get the bucket of this {@link ObjectResources}.
     *
     * @return {@link String}
     */
    public String getBucket() {
        return bucket;
    }

    /**
     * Set the bucket of this {@link ObjectResources}.
     *
     * @param bucket
     *            where resources exist
     */
    public void setBucket(String bucket) {
        checkAttributesAllowed();
        bucket = StringUtils.trimToNull(bucket);

        if (!Objects.equals(bucket, this.bucket)) {
            this.bucket = bucket;
            resetResourceCache();
        }
    }

    /**
     * Get the precision, semantically expressed "as".
     * 
     * @return {@link Precision}
     */
    public Precision getAs() {
        return as;
    }

    /**
     * Set the precision, semantically expressed "as". This affects only the
     * name property and {@link Object#toString()} value of generated
     * {@link ObjectResource}s.
     * 
     * @param as
     *            {@link Precision}
     */
    public void setAs(Precision as) {
        checkAttributesAllowed();
        if (as != this.as) {
            this.as = Objects.requireNonNull(as);
            resetResourceCache();
        }
    }

    /**
     * Learn whether the include/exclude patterns are to be applied with case
     * sensitivity.
     *
     * @return {@code boolean}
     */
    public boolean isCaseSensitive() {
        return caseSensitive;
    }

    /**
     * Set whether to apply include/exclude patterns with case sensitivity
     * (default {@code true}).
     *
     * @param caseSensitive
     *            {@code boolean}
     */
    public void setCaseSensitive(boolean caseSensitive) {
        checkAttributesAllowed();
        if (caseSensitive != this.caseSensitive) {
            this.caseSensitive = caseSensitive;
            resetResourceCache();
        }
    }

    /**
     * Get the delimiter of this {@link ObjectResources}.
     *
     * @return {@link String}
     */
    public String getDelimiter() {
        return delimiter;
    }

    /**
     * Set the delimiter of this {@link ObjectResources}.
     *
     * @param delimiter
     *            empty to use no delimiter
     */
    public void setDelimiter(String delimiter) {
        checkAttributesAllowed();
        delimiter = StringUtils.trimToNull(delimiter);
        if (!Objects.equals(delimiter, this.delimiter)) {
            this.delimiter = delimiter;
            resetResourceCache();
        }
    }

    /**
     * Learn whether the discovered {@link ObjectResource}s will be cached.
     *
     * @return {@code boolean}
     */
    public boolean isCache() {
        return cache;
    }

    /**
     * Set whether the discovered {@link ObjectResource}s should be cached,
     * default {@code true}.
     *
     * @param cache
     *            flag
     */
    public void setCache(boolean cache) {
        this.cache = cache;
        if (!cache) {
            resetResourceCache();
        }
    }

    /**
     * Learn whether to include S3 object prefixes as "directory" type
     * {@link Resource}s, default {@code false}.
     * 
     * @return {@code boolean}
     */
    public boolean isIncludePrefixes() {
        return includePrefixes;
    }

    /**
     * Set whether to include S3 object prefixes as "directory" type
     * {@link Resource}s, default {@code false}.
     * 
     * @param includePrefixes
     *            {@code boolean}
     */
    public void setIncludePrefixes(boolean includePrefixes) {
        checkAttributesAllowed();
        if (includePrefixes != this.includePrefixes) {
            this.includePrefixes = includePrefixes;
            resetResourceCache();
        }
    }

    /**
     * Add a nested {@link PatternSet}.
     *
     * @param patternSet
     *            to add
     */
    public void addConfigured(PatternSet patternSet) {
        checkChildrenAllowed();
        patterns.addConfiguredPatternset(patternSet);
        resetResourceCache();
    }

    /**
     * Add a nested include.
     *
     * @return {@link PatternSet.NameEntry}
     */
    public PatternSet.NameEntry createInclude() {
        checkChildrenAllowed();
        resetResourceCache();
        return patterns.createInclude();
    }

    /**
     * Add a nested includesfile.
     *
     * @return {@link PatternSet.PatternFileNameEntry}
     */
    public PatternSet.NameEntry createIncludesFile() {
        checkChildrenAllowed();
        resetResourceCache();
        return patterns.createIncludesFile();
    }

    /**
     * Add a nested exclude.
     *
     * @return {@link PatternSet.NameEntry}
     */
    public PatternSet.NameEntry createExclude() {
        checkChildrenAllowed();
        resetResourceCache();
        return patterns.createExclude();
    }

    /**
     * Add a nested excludesfile.
     *
     * @return {@link PatternSet.PatternFileNameEntry}
     */
    public PatternSet.NameEntry createExcludesFile() {
        checkChildrenAllowed();
        resetResourceCache();
        return patterns.createExcludesFile();
    }

    /**
     * Set includes patterns via attribute.
     *
     * @param includes
     *            patterns
     */
    public void setIncludes(String includes) {
        checkAttributesAllowed();
        resetResourceCache();
        patterns.setIncludes(includes);
    }

    /**
     * Set includes file via attribute.
     *
     * @param includesFile
     *            {@link File}
     */
    public void setIncludesFile(File includesFile) {
        checkAttributesAllowed();
        resetResourceCache();
        patterns.setIncludesfile(includesFile);
    }

    /**
     * Set excludes patterns via attribute.
     *
     * @param excludes
     *            patterns
     */
    public void setExcludes(String excludes) {
        checkAttributesAllowed();
        resetResourceCache();
        patterns.setExcludes(excludes);
    }

    /**
     * Set excludes file via attribute.
     *
     * @param excludesFile
     *            {@link File}
     */
    public void setExcludesFile(File excludesFile) {
        checkAttributesAllowed();
        resetResourceCache();
        patterns.setExcludesfile(excludesFile);
    }

    private S3Client s3() {
        return requireComponent(s3, Client.class).get();
    }

    private boolean isSelected(Resource resource) {
        return selectors.stream().anyMatch(sel -> sel.isSelected(resource));
    }

    private void resetResourceCache() {
        resourceCache = Optional.empty();
    }
}
