package org.eclipse.aether.transfer;

/*
 * 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.
 */

import java.nio.ByteBuffer;
import static java.util.Objects.requireNonNull;

import org.eclipse.aether.RepositorySystemSession;

/**
 * An event fired to a transfer listener during an artifact/metadata transfer.
 *
 * @see TransferListener
 * @see TransferEvent.Builder
 */
public final class TransferEvent
{

    /**
     * The type of the event.
     */
    public enum EventType
    {

        /**
         * @see TransferListener#transferInitiated(TransferEvent)
         */
        INITIATED,

        /**
         * @see TransferListener#transferStarted(TransferEvent)
         */
        STARTED,

        /**
         * @see TransferListener#transferProgressed(TransferEvent)
         */
        PROGRESSED,

        /**
         * @see TransferListener#transferCorrupted(TransferEvent)
         */
        CORRUPTED,

        /**
         * @see TransferListener#transferSucceeded(TransferEvent)
         */
        SUCCEEDED,

        /**
         * @see TransferListener#transferFailed(TransferEvent)
         */
        FAILED

    }

    /**
     * The type of the request/transfer being performed.
     */
    public enum RequestType
    {

        /**
         * Download artifact/metadata.
         */
        GET,

        /**
         * Check artifact/metadata existence only.
         */
        GET_EXISTENCE,

        /**
         * Upload artifact/metadata.
         */
        PUT,

    }

    private final EventType type;

    private final RequestType requestType;

    private final RepositorySystemSession session;

    private final TransferResource resource;

    private final ByteBuffer dataBuffer;

    private final long transferredBytes;

    private final Exception exception;

    TransferEvent( Builder builder )
    {
        type = builder.type;
        requestType = builder.requestType;
        session = builder.session;
        resource = builder.resource;
        dataBuffer = builder.dataBuffer;
        transferredBytes = builder.transferredBytes;
        exception = builder.exception;
    }

    /**
     * Gets the type of the event.
     * 
     * @return The type of the event, never {@code null}.
     */
    public EventType getType()
    {
        return type;
    }

    /**
     * Gets the type of the request/transfer.
     * 
     * @return The type of the request/transfer, never {@code null}.
     */
    public RequestType getRequestType()
    {
        return requestType;
    }

    /**
     * Gets the repository system session during which the event occurred.
     * 
     * @return The repository system session during which the event occurred, never {@code null}.
     */
    public RepositorySystemSession getSession()
    {
        return session;
    }

    /**
     * Gets the resource that is being transferred.
     * 
     * @return The resource being transferred, never {@code null}.
     */
    public TransferResource getResource()
    {
        return resource;
    }

    /**
     * Gets the total number of bytes that have been transferred since the download/upload of the resource was started.
     * If a download has been resumed, the returned count includes the bytes that were already downloaded during the
     * previous attempt. In other words, the ratio of transferred bytes to the content length of the resource indicates
     * the percentage of transfer completion.
     * 
     * @return The total number of bytes that have been transferred since the transfer started, never negative.
     * @see #getDataLength()
     * @see TransferResource#getResumeOffset()
     */
    public long getTransferredBytes()
    {
        return transferredBytes;
    }

    /**
     * Gets the byte buffer holding the transferred bytes since the last event. A listener must assume this buffer to be
     * owned by the event source and must not change any byte in this buffer. Also, the buffer is only valid for the
     * duration of the event callback, i.e. the next event might reuse the same buffer (with updated contents).
     * Therefore, if the actual event processing is deferred, the byte buffer would have to be cloned to create an
     * immutable snapshot of its contents.
     * 
     * @return The (read-only) byte buffer or {@code null} if not applicable to the event, i.e. if the event type is not
     *         {@link EventType#PROGRESSED}.
     */
    public ByteBuffer getDataBuffer()
    {
        return ( dataBuffer != null ) ? dataBuffer.asReadOnlyBuffer() : null;
    }

    /**
     * Gets the number of bytes that have been transferred since the last event.
     * 
     * @return The number of bytes that have been transferred since the last event, possibly zero but never negative.
     * @see #getTransferredBytes()
     */
    public int getDataLength()
    {
        return ( dataBuffer != null ) ? dataBuffer.remaining() : 0;
    }

    /**
     * Gets the error that occurred during the transfer.
     * 
     * @return The error that occurred or {@code null} if none.
     */
    public Exception getException()
    {
        return exception;
    }

    @Override
    public String toString()
    {
        return getRequestType() + " " + getType() + " " + getResource();
    }

    /**
     * A builder to create transfer events.
     */
    public static final class Builder
    {

        EventType type;

        RequestType requestType;

        RepositorySystemSession session;

        TransferResource resource;

        ByteBuffer dataBuffer;

        long transferredBytes;

        Exception exception;

        /**
         * Creates a new transfer event builder for the specified session and the given resource.
         *
         * @param session The repository system session, must not be {@code null}.
         * @param resource The resource being transferred, must not be {@code null}.
         */
        public Builder( RepositorySystemSession session, TransferResource resource )
        {
            this.session = requireNonNull( session, "repository system session cannot be null" );
            this.resource = requireNonNull( resource, "transfer resource cannot be null" );
            type = EventType.INITIATED;
            requestType = RequestType.GET;
        }

        private Builder( Builder prototype )
        {
            session = prototype.session;
            resource = prototype.resource;
            type = prototype.type;
            requestType = prototype.requestType;
            dataBuffer = prototype.dataBuffer;
            transferredBytes = prototype.transferredBytes;
            exception = prototype.exception;
        }

        /**
         * Creates a new transfer event builder from the current values of this builder. The state of this builder
         * remains unchanged.
         * 
         * @return The new event builder, never {@code null}.
         */
        public Builder copy()
        {
            return new Builder( this );
        }

        /**
         * Sets the type of the event and resets event-specific fields. In more detail, the data buffer and the
         * exception fields are set to {@code null}. Furthermore, the total number of transferred bytes is set to
         * {@code 0} if the event type is {@link EventType#STARTED}.
         *
         * @param type The type of the event, must not be {@code null}.
         * @return This event builder for chaining, never {@code null}.
         */
        public Builder resetType( EventType type )
        {
            this.type = requireNonNull( type, "event type cannot be null" );
            dataBuffer = null;
            exception = null;
            switch ( type )
            {
                case INITIATED:
                case STARTED:
                    transferredBytes = 0L;
                default:
            }
            return this;
        }

        /**
         * Sets the type of the event. When re-using the same builder to generate a sequence of events for one transfer,
         * {@link #resetType(TransferEvent.EventType)} might be more handy.
         *
         * @param type The type of the event, must not be {@code null}.
         * @return This event builder for chaining, never {@code null}.
         */
        public Builder setType( EventType type )
        {
            this.type = requireNonNull( type, "event type cannot be null" );
            return this;
        }

        /**
         * Sets the type of the request/transfer.
         *
         * @param requestType The request/transfer type, must not be {@code null}.
         * @return This event builder for chaining, never {@code null}.
         */
        public Builder setRequestType( RequestType requestType )
        {
            this.requestType = requireNonNull( requestType, "request type cannot be null" );
            return this;
        }

        /**
         * Sets the total number of bytes that have been transferred so far during the download/upload of the resource.
         * If a download is being resumed, the count must include the bytes that were already downloaded in the previous
         * attempt and from which the current transfer started. In this case, the event type {@link EventType#STARTED}
         * should indicate from what byte the download resumes.
         * 
         * @param transferredBytes The total number of bytes that have been transferred so far during the
         *            download/upload of the resource, must not be negative.
         * @return This event builder for chaining, never {@code null}.
         * @see TransferResource#setResumeOffset(long)
         */
        public Builder setTransferredBytes( long transferredBytes )
        {
            if ( transferredBytes < 0L )
            {
                throw new IllegalArgumentException( "number of transferred bytes cannot be negative" );
            }
            this.transferredBytes = transferredBytes;
            return this;
        }

        /**
         * Increments the total number of bytes that have been transferred so far during the download/upload.
         *
         * @param transferredBytes The number of bytes that have been transferred since the last event, must not be
         *            negative.
         * @return This event builder for chaining, never {@code null}.
         */
        public Builder addTransferredBytes( long transferredBytes )
        {
            if ( transferredBytes < 0L )
            {
                throw new IllegalArgumentException( "number of transferred bytes cannot be negative" );
            }
            this.transferredBytes += transferredBytes;
            return this;
        }

        /**
         * Sets the byte buffer holding the transferred bytes since the last event.
         * 
         * @param buffer The byte buffer holding the transferred bytes since the last event, may be {@code null} if not
         *            applicable to the event.
         * @param offset The starting point of valid bytes in the array.
         * @param length The number of valid bytes, must not be negative.
         * @return This event builder for chaining, never {@code null}.
         */
        public Builder setDataBuffer( byte[] buffer, int offset, int length )
        {
            return setDataBuffer( ( buffer != null ) ? ByteBuffer.wrap( buffer, offset, length ) : null );
        }

        /**
         * Sets the byte buffer holding the transferred bytes since the last event.
         * 
         * @param dataBuffer The byte buffer holding the transferred bytes since the last event, may be {@code null} if
         *            not applicable to the event.
         * @return This event builder for chaining, never {@code null}.
         */
        public Builder setDataBuffer( ByteBuffer dataBuffer )
        {
            this.dataBuffer = dataBuffer;
            return this;
        }

        /**
         * Sets the error that occurred during the transfer.
         * 
         * @param exception The error that occurred during the transfer, may be {@code null} if none.
         * @return This event builder for chaining, never {@code null}.
         */
        public Builder setException( Exception exception )
        {
            this.exception = exception;
            return this;
        }

        /**
         * Builds a new transfer event from the current values of this builder. The state of the builder itself remains
         * unchanged.
         * 
         * @return The transfer event, never {@code null}.
         */
        public TransferEvent build()
        {
            return new TransferEvent( this );
        }

    }

}
