/*
 * Copyright 2010 SpringSource
 *
 * Licensed 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 net.anzix.aws.maven;

import org.apache.maven.wagon.ConnectionException;
import org.apache.maven.wagon.ResourceDoesNotExistException;
import org.apache.maven.wagon.TransferFailedException;
import org.apache.maven.wagon.Wagon;
import org.apache.maven.wagon.authentication.AuthenticationException;
import org.apache.maven.wagon.authentication.AuthenticationInfo;
import org.apache.maven.wagon.authorization.AuthorizationException;
import org.apache.maven.wagon.events.SessionListener;
import org.apache.maven.wagon.events.TransferEvent;
import org.apache.maven.wagon.events.TransferListener;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.proxy.ProxyInfoProvider;
import org.apache.maven.wagon.repository.Repository;
import org.apache.maven.wagon.resource.Resource;

import java.io.File;
import java.util.List;

/**
 * An abstract implementation of the Wagon interface. This implementation
 * manages listener and other common behaviors.
 * 
 * @author Ben Hale
 * @since 1.1
 */
public abstract class AbstractWagon implements Wagon {

    private boolean interactive;

    private Repository repository;

    private boolean supportsDirectoryCopy;

    private SessionListenerSupport sessionListeners = new SessionListenerSupport(this);

    private TransferListenerSupport transferListeners = new TransferListenerSupport(this);

    private int timeout;

    protected AbstractWagon(boolean supportsDirectoryCopy) {
        this.supportsDirectoryCopy = supportsDirectoryCopy;
    }

    public final void addSessionListener(SessionListener listener) {
        sessionListeners.addListener(listener);
    }

    protected final SessionListenerSupport getSessionListeners() {
        return sessionListeners;
    }

    public final boolean hasSessionListener(SessionListener listener) {
        return sessionListeners.hasListener(listener);
    }

    public final void removeSessionListener(SessionListener listener) {
        sessionListeners.removeListener(listener);
    }

    public final void addTransferListener(TransferListener listener) {
        transferListeners.addListener(listener);
    }

    protected final TransferListenerSupport getTransferListeners() {
        return transferListeners;
    }

    public final boolean hasTransferListener(TransferListener listener) {
        return transferListeners.hasListener(listener);
    }

    public final void removeTransferListener(TransferListener listener) {
        transferListeners.removeListener(listener);
    }

    public final Repository getRepository() {
        return repository;
    }

    public final boolean isInteractive() {
        return interactive;
    }

    public final void setInteractive(boolean interactive) {
        this.interactive = interactive;
    }

    public final void connect(Repository source) throws ConnectionException, AuthenticationException {
        connect(source, null, (ProxyInfoProvider) null);
    }

    public final void connect(Repository source, ProxyInfo proxyInfo) throws ConnectionException,
            AuthenticationException {
        connect(source, null, proxyInfo);
    }

    public final void connect(Repository source, AuthenticationInfo authenticationInfo) throws ConnectionException,
            AuthenticationException {
        connect(source, authenticationInfo, (ProxyInfoProvider) null);
    }

    public void connect(Repository source, ProxyInfoProvider proxyInfoProvider) throws ConnectionException, AuthenticationException {
        connect(source, null, proxyInfoProvider);
    }

    public void connect(Repository source, AuthenticationInfo authenticationInfo, ProxyInfo proxyInfo) throws ConnectionException, AuthenticationException {
        final ProxyInfo proxy = proxyInfo;
        connect(source, authenticationInfo, new ProxyInfoProvider() {

            public ProxyInfo getProxyInfo(String protocol) {
                if (protocol == null || proxy == null || protocol.equalsIgnoreCase(proxy.getType())) {
                    return proxy;
                } else {
                    return null;
                }
            }
        });
    }

    public final void connect(Repository source, AuthenticationInfo authenticationInfo, ProxyInfoProvider proxyInfoProvider)
            throws ConnectionException, AuthenticationException {
        repository = source;
        sessionListeners.fireSessionOpening();
        try {
            connectToRepository(source, authenticationInfo, proxyInfoProvider);
        } catch (ConnectionException e) {
            sessionListeners.fireSessionConnectionRefused();
            throw e;
        } catch (AuthenticationException e) {
            sessionListeners.fireSessionConnectionRefused();
            throw e;
        } catch (Exception e) {
            sessionListeners.fireSessionConnectionRefused();
            throw new ConnectionException("Could not connect to repository", e);
        }
        sessionListeners.fireSessionLoggedIn();
        sessionListeners.fireSessionOpened();
    }

    public final void disconnect() throws ConnectionException {
        sessionListeners.fireSessionDisconnecting();
        try {
            disconnectFromRepository();
        } catch (ConnectionException e) {
            sessionListeners.fireSessionConnectionRefused();
            throw e;
        } catch (Exception e) {
            sessionListeners.fireSessionConnectionRefused();
            throw new ConnectionException("Could not disconnect from repository", e);
        }
        sessionListeners.fireSessionLoggedOff();
        sessionListeners.fireSessionDisconnected();
    }

    public final void get(String resourceName, File destination) throws TransferFailedException,
            ResourceDoesNotExistException, AuthorizationException {
        Resource resource = new Resource(resourceName);
        transferListeners.fireTransferInitiated(resource, TransferEvent.REQUEST_GET);
        transferListeners.fireTransferStarted(resource, TransferEvent.REQUEST_GET);

        try {
            getResource(resourceName, destination, new TransferProgress(resource, TransferEvent.REQUEST_GET,
                    transferListeners));
            transferListeners.fireTransferCompleted(resource, TransferEvent.REQUEST_GET);
        } catch (TransferFailedException e) {
            throw e;
        } catch (ResourceDoesNotExistException e) {
            throw e;
        } catch (AuthorizationException e) {
            throw e;
        } catch (Exception e) {
            transferListeners.fireTransferError(resource, TransferEvent.REQUEST_GET, e);
            throw new TransferFailedException("Transfer of resource " + destination + "failed", e);
        }
    }

    @SuppressWarnings("unchecked")
    public final List getFileList(String destinationDirectory) throws TransferFailedException,
            ResourceDoesNotExistException, AuthorizationException {
        try {
            return listDirectory(destinationDirectory);
        } catch (TransferFailedException e) {
            throw e;
        } catch (ResourceDoesNotExistException e) {
            throw e;
        } catch (AuthorizationException e) {
            throw e;
        } catch (Exception e) {
            sessionListeners.fireSessionError(e);
            throw new TransferFailedException("Listing of directory " + destinationDirectory + "failed", e);
        }
    }

    public final boolean getIfNewer(String resourceName, File destination, long timestamp)
            throws TransferFailedException, ResourceDoesNotExistException, AuthorizationException {
        Resource resource = new Resource(resourceName);
        try {
            if (isRemoteResourceNewer(resourceName, timestamp)) {
                get(resourceName, destination);
                return true;
            } else {
                return false;
            }
        } catch (TransferFailedException e) {
            throw e;
        } catch (ResourceDoesNotExistException e) {
            throw e;
        } catch (AuthorizationException e) {
            throw e;
        } catch (Exception e) {
            transferListeners.fireTransferError(resource, TransferEvent.REQUEST_GET, e);
            throw new TransferFailedException("Transfer of resource " + destination + "failed", e);
        }
    }

    public final void openConnection() throws ConnectionException, AuthenticationException {
        // Nothing to do here (never called by the wagon manager)
    }

    public final void put(File source, String destination) throws TransferFailedException,
            ResourceDoesNotExistException, AuthorizationException {
        Resource resource = new Resource(destination);
        transferListeners.fireTransferInitiated(resource, TransferEvent.REQUEST_PUT);
        transferListeners.fireTransferStarted(resource, TransferEvent.REQUEST_PUT);

        try {
            putResource(source, destination, new TransferProgress(resource, TransferEvent.REQUEST_PUT,
                    transferListeners));
            transferListeners.fireTransferCompleted(resource, TransferEvent.REQUEST_PUT);
        } catch (TransferFailedException e) {
            throw e;
        } catch (ResourceDoesNotExistException e) {
            throw e;
        } catch (AuthorizationException e) {
            throw e;
        } catch (Exception e) {
            transferListeners.fireTransferError(resource, TransferEvent.REQUEST_PUT, e);
            throw new TransferFailedException("Transfer of resource " + destination + "failed", e);
        }
    }

    public final void putDirectory(File sourceDirectory, String destinationDirectory) throws TransferFailedException,
            ResourceDoesNotExistException, AuthorizationException {
        for (File f : sourceDirectory.listFiles()) {
            put(f, destinationDirectory + "/" + f.getName());
        }
    }

    public final boolean resourceExists(String resourceName) throws TransferFailedException, AuthorizationException {
        try {
            return doesRemoteResourceExist(resourceName);
        } catch (TransferFailedException e) {
            throw e;
        } catch (AuthorizationException e) {
            throw e;
        } catch (Exception e) {
            sessionListeners.fireSessionError(e);
            throw new TransferFailedException("Listing of resource " + resourceName + "failed", e);
        }
    }

    public final boolean supportsDirectoryCopy() {
        return supportsDirectoryCopy;
    }

    public int getTimeout() {
        return timeout;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    /**
     * Subclass must implement with specific connection behavior
     *
     * @param source The repository connection information
     * @param authenticationInfo Authentication information, if any
     * @param proxyInfo Proxy information, if any
     * @throws Exception Implementations can throw any exception and it will be
     * handled by the base class
     */
    protected abstract void connectToRepository(Repository source, AuthenticationInfo authenticationInfo,
            ProxyInfoProvider proxyInfo) throws Exception;

    /**
     * Subclass must implement with specific detection behavior
     *
     * @param resourceName The remote resource to detect
     * @return true if the remote resource exists
     * @throws Exception Implementations can throw any exception and it will be
     * handled by the base class
     */
    protected abstract boolean doesRemoteResourceExist(String resourceName) throws Exception;

    /**
     * Subclasses must implement with specific disconnection behavior
     *
     * @throws Exception Implementations can throw any exception and it will be
     * handled by the base class
     */
    protected abstract void disconnectFromRepository() throws Exception;

    /**
     * Subclass must implement with specific get behavior
     *
     * @param resourceName The name of the remote resource to read
     * @param destination The local file to write to
     * @param progress A progress notifier for the upload. It must be used or
     * hashes will not be calculated correctly
     * @throws Exception Implementations can throw any exception and it will be
     * handled by the base class
     */
    protected abstract void getResource(String resourceName, File destination, TransferProgress progress)
            throws Exception;

    /**
     * Subclass must implement with newer detection behavior
     *
     * @param resourceName The name of the resource being compared
     * @param timestamp The timestamp to compare against
     * @return true if the current version of the resource is newer than the
     * timestamp
     * @throws Exception Implementations can throw any exception and it will be
     * handled by the base class
     */
    protected abstract boolean isRemoteResourceNewer(String resourceName, long timestamp) throws Exception;

    /**
     * Subclass must implement with specific directory listing behavior
     *
     * @param directory The directory to list files in
     * @return A collection of file names
     * @throws Exception Implementations can throw any exception and it will be
     * handled by the base class
     */
    protected abstract List<String> listDirectory(String directory) throws Exception;

    /**
     * Subclasses must implement with specific put behavior
     *
     * @param source The local source file to read from
     * @param destination The name of the remote resource to write to
     * @param progress A progress notifier for the upload. It must be used or
     * hashes will not be calculated correctly
     * @throws Exception Implementations can throw any exception and it will be
     * handled by the base class
     */
    protected abstract void putResource(File source, String destination, TransferProgress progress) throws Exception;
}
