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

import java.util.Comparator;
import java.util.Optional;
import java.util.function.BiPredicate;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.regex.Pattern;

import org.apache.tools.ant.Project;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.resources.comparators.ResourceComparator;
import org.apache.tools.ant.types.resources.selectors.ResourceSelector;
import org.apache.tools.ant.types.selectors.SelectorUtils;
import org.apache.tools.ant.util.StringUtils;

/**
 * S3 {@link ResourceComparator}/{@link ResourceSelector} base/class
 * organization.
 */
public abstract class CompareSelect extends ResourceComparator implements ResourceSelector, ProjectUtils {

    /**
     * {@link CompareSelect} {@link ForStringAttribute}.
     */
    public static abstract class ForStringAttribute extends CompareSelect {

        /**
         * "Match as" strategy.
         */
        public enum MatchAs {
            /**
             * Ant extended glob matching.
             */
            glob {

                @Override
                Predicate<String> matcher(final CompareSelect.ForStringAttribute selector) {
                    return s -> SelectorUtils.matchPath(selector.getSpecification(), s, selector.isCaseSensitive());
                }
            },
            /**
             * Literal matching.
             */
            literal {

                @Override
                Predicate<String> matcher(final CompareSelect.ForStringAttribute selector) {
                    final BiPredicate<String, String> impl =
                        selector.isCaseSensitive() ? String::equals : String::equalsIgnoreCase;
                    return s -> impl.test(selector.getSpecification(), s);
                }
            },
            /**
             * Regex matching.
             */
            regex {

                @Override
                Predicate<String> matcher(final CompareSelect.ForStringAttribute selector) {
                    return Pattern
                        .compile(selector.getSpecification(), selector.isCaseSensitive() ? 0 : Pattern.CASE_INSENSITIVE)
                        .asPredicate();
                }
            };

            /**
             * Render a {@link Predicate} from {@code selector}'s settings.
             *
             * @param selector
             * @return {@link Predicate}
             */
            abstract Predicate<String> matcher(CompareSelect.ForStringAttribute selector);
        }

        private final Comparator<Resource> cmp;
        private final StringBuffer specification = new StringBuffer();
        private MatchAs matchAs = MatchAs.literal;
        private boolean caseSensitive = true;

        private volatile Predicate<String> predicate;

        /**
         * Create a new {@link CompareSelect.ForStringAttribute}.
         *
         * @param project
         */
        protected ForStringAttribute(final Project project) {
            super(project);
            cmp = comparingS3(this::extractValueFrom);
        }

        /**
         * Add nested text by which the value to compare is set.
         *
         * @param text
         */
        public void addText(final String text) {
            Optional.ofNullable(StringUtils.trimToNull(text)).map(getProject()::replaceProperties).map(String::trim)
                .ifPresent(t -> {
                    specification.append(t);
                    predicate = null;
                });
        }

        /**
         * Get "match as" strategy (default {@link MatchAs#LITERAL}.
         *
         * @return {@link MatchAs}
         */
        public MatchAs getMatchAs() {
            return matchAs;
        }

        /**
         * Set "match as" strategy.
         *
         * @param matchAs
         */
        public void setMatchAs(final MatchAs matchAs) {
            Exceptions.raiseIf(matchAs == null, buildException(), "@matchas may not be null");

            if (this.matchAs != matchAs) {
                this.matchAs = matchAs;
                predicate = null;
            }
        }

        /**
         * Learn whether matching should be performed in a case-sensitive manner
         * (default {@code true}).
         *
         * @return {@code boolean}
         */
        public final boolean isCaseSensitive() {
            return caseSensitive;
        }

        /**
         * Set whether matching should be performed in a case-sensitive manner.
         *
         * @param caseSensitive
         */
        public void setCaseSensitive(final boolean caseSensitive) {
            if (caseSensitive != this.caseSensitive) {
                this.caseSensitive = caseSensitive;
                predicate = null;
            }
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isSelected(final Resource r) {
            return r.asOptional(ObjectResource.class).map(this::extractValueFrom).filter(predicate()).isPresent();
        }

        /**
         * Extract the value to be matched from the specified
         * {@link ObjectResource}.
         *
         * @param obj
         * @return {@link String}
         */
        protected abstract String extractValueFrom(ObjectResource obj);

        /**
         * {@inheritDoc}
         */
        @Override
        protected int resourceCompare(final Resource foo, final Resource bar) {
            return cmp.compare(foo, bar);
        }

        /**
         * Get the specification against which values will be matched.
         *
         * @return {@link String}
         */
        String getSpecification() {
            return getProject().replaceProperties(specification.toString()).trim();
        }

        private Predicate<String> predicate() {
            if (predicate == null) {
                predicate = matchAs.matcher(this);
            }
            return predicate;
        }
    }

    /**
     * Select {@link ObjectResource} by bucket.
     */
    public static class Bucket extends CompareSelect.ForStringAttribute {

        /**
         * Create a new {@link Bucket} selector.
         *
         * @param project
         */
        public Bucket(final Project project) {
            super(project);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected String extractValueFrom(final ObjectResource obj) {
            return obj.getBucket();
        }
    }

    /**
     * Select {@link ObjectResource} by key.
     */
    public static class Key extends CompareSelect.ForStringAttribute {

        /**
         * Create a new {@link Key} selector.
         *
         * @param project
         */
        public Key(final Project project) {
            super(project);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected String extractValueFrom(final ObjectResource obj) {
            return obj.getKey();
        }
    }

    /**
     * Select {@link ObjectResource} by content type.
     */
    public static class ContentType extends CompareSelect.ForStringAttribute {

        /**
         * Create a new {@link ContentType} selector.
         *
         * @param project
         */
        public ContentType(final Project project) {
            super(project);
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected String extractValueFrom(final ObjectResource obj) {
            return obj.getContentType();
        }
    }

    /**
     * Select {@link ObjectResource} by metadata.
     */
    public static class Meta extends CompareSelect.ForStringAttribute {
        private String key;

        /**
         * Create a new {@link Meta} selector.
         *
         * @param project
         */
        public Meta(final Project project) {
            super(project);
        }

        /**
         * Get the user metadata key to match on.
         *
         * @return {@link String}
         */
        public String getKey() {
            return key;
        }

        /**
         * Set the user metadata key to match on.
         *
         * @param key
         */
        public void setKey(final String key) {
            this.key = key;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected String extractValueFrom(final ObjectResource obj) {
            return obj.getMetadata().get(getKey());
        }
    }

    /**
     * Select {@link ObjectResource} by tag.
     */
    public static class Tag extends CompareSelect.ForStringAttribute {
        private String key;

        /**
         * Create a new {@link Tag} selector.
         *
         * @param project
         */
        public Tag(final Project project) {
            super(project);
        }

        /**
         * Get the tag key to match on.
         *
         * @return {@link String}
         */
        public String getKey() {
            return key;
        }

        /**
         * Set the tag key to match on.
         *
         * @param key
         */
        public void setKey(final String key) {
            this.key = key;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected String extractValueFrom(final ObjectResource obj) {
            return obj.getTagging().get(getKey());
        }
    }

    /**
     * Select {@link ObjectResource} by version ID.
     */
    public static class VersionId extends CompareSelect.ForStringAttribute {

        /**
         * Create a new {@link VersionId} selector.
         * 
         * @param project
         */
        public VersionId(Project project) {
            super(project);
        }

        @Override
        protected String extractValueFrom(ObjectResource obj) {
            return obj.getVersionId();
        }
    }

    /**
     * {@link CompareSelect} {@link ForBooleanAttribute}.
     */
    public static abstract class ForBooleanAttribute extends CompareSelect {

        private final Predicate<ObjectResource> test;

        /**
         * Create a new {@link CompareSelect.ForBooleanAttribute}.
         * 
         * @param project
         */
        protected ForBooleanAttribute(Project project, Predicate<ObjectResource> test) {
            super(project);
            this.test = test;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected int resourceCompare(Resource foo, Resource bar) {
            return Boolean.compare(isSelected(foo), isSelected(bar));
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isSelected(Resource r) {
            return r.asOptional(ObjectResource.class).filter(test).isPresent();
        }
    }

    /**
     * Select {@link ObjectResource} on the basis of whether it is a delete
     * marker.
     */
    public static class DeleteMarker extends CompareSelect.ForBooleanAttribute {

        /**
         * Create a new {@link DeleteMarker}.
         * 
         * @param project
         */
        public DeleteMarker(Project project) {
            super(project, ObjectResource::isDeleteMarker);
        }
    }

    /**
     * Select {@link ObjectResource} on the basis of being the latest version.
     */
    public static class Latest extends CompareSelect.ForBooleanAttribute {

        /**
         * Create a new {@link Latest}.
         * 
         * @param project
         */
        public Latest(Project project) {
            super(project, ObjectResource::isLatest);
        }
    }

    /**
     * Select by object {@link Precision}.
     */
    public static class ByPrecision extends CompareSelect {
        private static final Comparator<Resource> COMPARATOR = comparingS3(ObjectResource::getPrecision);

        private Precision precision;

        /**
         * Create a new {@link ByPrecision}.
         * 
         * @param project
         */
        public ByPrecision(Project project) {
            super(project);
        }

        /**
         * Get the precision.
         * 
         * @return Precision
         */
        public Precision getPrecision() {
            return precision;
        }

        /**
         * Set the precision.
         * 
         * @param precision
         *            Precision
         */
        public void setPrecision(Precision precision) {
            this.precision = precision;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public boolean isSelected(Resource r) {
            Exceptions.raiseIf(getPrecision() == null, IllegalStateException::new, "@precision not specified");
            return r.asOptional(ObjectResource.class).map(ObjectResource::getPrecision).filter(p -> p == getPrecision())
                .isPresent();
        }

        /**
         * {@inheritDoc}
         */
        @Override
        protected int resourceCompare(Resource foo, Resource bar) {
            return COMPARATOR.compare(foo, bar);
        }
    }

    private static final Function<Resource, ObjectResource> S3O = r -> r.as(ObjectResource.class);

    private static final <T extends Comparable<T>> Comparator<Resource> comparingS3(
        Function<ObjectResource, ? extends T> xform) {
        return Comparator.nullsFirst(Comparator.comparing(S3O.andThen(r -> r == null ? null : xform.apply(r))));
    }

    /**
     * Create a {@link CompareSelect} instance.
     * 
     * @param project
     */
    protected CompareSelect(Project project) {
        setProject(project);
    }
}