/*
 *  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.IOException;
import java.util.Objects;
import java.util.Optional;
import java.util.Vector;
import java.util.function.Supplier;

import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.types.FilterChain;
import org.apache.tools.ant.types.FilterSetCollection;
import org.apache.tools.ant.types.Resource;
import org.apache.tools.ant.types.ResourceFactory;
import org.apache.tools.ant.types.resources.FileProvider;
import org.apache.tools.ant.util.StringUtils;

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

/**
 * Put {@link Resource}s into an S3 bucket.
 */
public class Put extends CopyResources {

    private Supplier<S3Client> s3;
    private String bucket;

    /**
     * Add a configured {@link Client}.
     *
     * @param s3
     */
    public void addConfigured(Client s3) {
        if (this.s3 != null) {
            throw new BuildException("S3 client already specified");
        }
        this.s3 = Objects.requireNonNull(s3);
    }

    /**
     * Set the {@link Client} by reference.
     *
     * @param refid
     */
    public void setClientRefid(String refid) {
        Objects.requireNonNull(StringUtils.trimToNull(refid), "@clientrefid must not be null/empty/blank");

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

    /**
     * Get the bucket to which target objects should be written.
     *
     * @return {@link String}
     */
    public String getBucket() {
        return bucket;
    }

    /**
     * Set the bucket to which target objects should be written.
     *
     * @param bucket
     */
    public void setBucket(String bucket) {
        this.bucket = StringUtils.trimToNull(bucket);
    }

    /**
     * Disable {@code append}.
     *
     * @param append
     * @throws BuildException
     *             if {@code append == true}
     */
    @Override
    public void setAppend(boolean append) {
        Exceptions.raiseIf(append, buildException(), "@append not supported by %s", getTaskName());
    }

    /**
     * Disable {@code preserveLastModified}.
     *
     * @param preserveLastModified
     * @throws BuildException
     *             if {@code preserveLastModified == true}
     */
    @Override
    public void setPreserveLastModified(boolean preserveLastModified) {
        Exceptions.raiseIf(preserveLastModified, buildException(), "@preserveLastModified not supported by %s",
            getTaskName());
    }

    /**
     * Enforce "always overwrite."
     * 
     * @return {@code true}
     */
    @Override
    public boolean isOverwrite() {
        return true;
    }

    /**
     * Disable {@code overwrite}.
     * 
     * @param overwrite
     * @throws BuildException
     *             if {@code overwrite == false}
     */
    @Override
    public void setOverwrite(boolean overwrite) {
        Exceptions.raiseUnless(overwrite, buildException(), "%s only operates in overwrite mode", getTaskName());
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected ResourceFactory resourceFactory() {
        final S3Client client = s3();
        final String _bucket = require(getBucket(), "@bucket");
        final String s = String.format("bucket %s", _bucket);

        return new ResourceFactory() {
            @Override
            public Resource getResource(String key) {
                return new ObjectResource(getProject(), client, _bucket, key);
            }

            @Override
            public String toString() {
                return s;
            }
        };
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void copyResource(Resource source, Resource dest, FilterSetCollection filters,
        final Vector<FilterChain> filterChains) throws IOException {

        while (filterChains.isEmpty() && !filters.hasFilters()) {
            final ObjectResource target = dest.as(ObjectResource.class);

            final String whyNot;

            if (source == dest) {
                whyNot = "Source and target resources are same runtime object %1$s";
            } else if (target.fullyEquals(source)) {
                whyNot = "Source and target resources are same fully-equal s3 object %1$s";
            } else {
                final Optional<FileProvider> fp = source.asOptional(FileProvider.class);
                if (fp.isPresent()) {
                    // use dedicated File-based put for simple File copy:
                    target.put(s3(), fp.get().getFile());
                    return;
                }
                break;
            }
            log(whyNot + " and no filters specified; nothing to do", source, target);
        }
        super.copyResource(source, dest, filters, filterChains);
    }

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