package org.eclipse.aether.internal.impl;

/*
 * 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 static org.junit.Assert.*;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.eclipse.aether.RepositorySystemSession;
import org.eclipse.aether.artifact.Artifact;
import org.eclipse.aether.internal.test.util.TestFileUtils;
import org.eclipse.aether.metadata.Metadata;
import org.eclipse.aether.spi.connector.ArtifactDownload;
import org.eclipse.aether.spi.connector.ArtifactUpload;
import org.eclipse.aether.spi.connector.MetadataDownload;
import org.eclipse.aether.spi.connector.MetadataUpload;
import org.eclipse.aether.spi.connector.RepositoryConnector;
import org.eclipse.aether.spi.connector.Transfer;
import org.eclipse.aether.transfer.ArtifactTransferException;
import org.eclipse.aether.transfer.MetadataTransferException;
import org.eclipse.aether.transfer.TransferEvent;
import org.eclipse.aether.transfer.TransferListener;
import org.eclipse.aether.transfer.TransferResource;

/**
 * A repository connector recording all get/put-requests and faking the results.
 */
class RecordingRepositoryConnector
    implements RepositoryConnector
{

    RepositorySystemSession session;

    boolean fail;

    private Artifact[] expectGet;

    private Artifact[] expectPut;

    private Metadata[] expectGetMD;

    private Metadata[] expectPutMD;

    private List<Artifact> actualGet = new ArrayList<Artifact>();

    private List<Metadata> actualGetMD = new ArrayList<Metadata>();

    private List<Artifact> actualPut = new ArrayList<Artifact>();

    private List<Metadata> actualPutMD = new ArrayList<Metadata>();

    public RecordingRepositoryConnector( RepositorySystemSession session, Artifact[] expectGet, Artifact[] expectPut,
                                         Metadata[] expectGetMD, Metadata[] expectPutMD )
    {
        this.session = session;
        this.expectGet = expectGet;
        this.expectPut = expectPut;
        this.expectGetMD = expectGetMD;
        this.expectPutMD = expectPutMD;
    }

    public RecordingRepositoryConnector( RepositorySystemSession session )
    {
        this.session = session;
    }

    public RecordingRepositoryConnector()
    {
    }

    public void get( Collection<? extends ArtifactDownload> artifactDownloads,
                     Collection<? extends MetadataDownload> metadataDownloads )
    {
        try
        {
            if ( artifactDownloads != null )
            {
                for ( ArtifactDownload download : artifactDownloads )
                {
                    fireInitiated( download );
                    Artifact artifact = download.getArtifact();
                    this.actualGet.add( artifact );
                    if ( fail )
                    {
                        download.setException( new ArtifactTransferException( artifact, null, "forced failure" ) );
                    }
                    else
                    {
                        TestFileUtils.writeString( download.getFile(), artifact.toString() );
                    }
                    fireDone( download );
                }
            }
            if ( metadataDownloads != null )
            {
                for ( MetadataDownload download : metadataDownloads )
                {
                    fireInitiated( download );
                    Metadata metadata = download.getMetadata();
                    this.actualGetMD.add( metadata );
                    if ( fail )
                    {
                        download.setException( new MetadataTransferException( metadata, null, "forced failure" ) );
                    }
                    else
                    {
                        TestFileUtils.writeString( download.getFile(), metadata.toString() );
                    }
                    fireDone( download );
                }
            }
        }
        catch ( Exception e )
        {
            throw new IllegalStateException( e );
        }
    }

    public void put( Collection<? extends ArtifactUpload> artifactUploads,
                     Collection<? extends MetadataUpload> metadataUploads )
    {
        try
        {
            if ( artifactUploads != null )
            {
                for ( ArtifactUpload upload : artifactUploads )
                {
                    // mimic "real" connector
                    fireInitiated( upload );
                    if ( upload.getFile() == null )
                    {
                        upload.setException( new ArtifactTransferException( upload.getArtifact(), null, "no file" ) );
                    }
                    else if ( fail )
                    {
                        upload.setException( new ArtifactTransferException( upload.getArtifact(), null,
                                                                            "forced failure" ) );
                    }
                    this.actualPut.add( upload.getArtifact() );
                    fireDone( upload );
                }
            }
            if ( metadataUploads != null )
            {
                for ( MetadataUpload upload : metadataUploads )
                {
                    // mimic "real" connector
                    fireInitiated( upload );
                    if ( upload.getFile() == null )
                    {
                        upload.setException( new MetadataTransferException( upload.getMetadata(), null, "no file" ) );
                    }
                    else if ( fail )
                    {
                        upload.setException( new MetadataTransferException( upload.getMetadata(), null,
                                                                            "forced failure" ) );
                    }
                    this.actualPutMD.add( upload.getMetadata() );
                    fireDone( upload );
                }
            }
        }
        catch ( Exception e )
        {
            throw new IllegalStateException( e );
        }
    }

    private void fireInitiated( Transfer transfer )
        throws Exception
    {
        TransferListener listener = transfer.getListener();
        if ( listener == null )
        {
            return;
        }
        TransferEvent.Builder event =
            new TransferEvent.Builder( session, new TransferResource( null, null, null, null, transfer.getTrace() ) );
        event.setType( TransferEvent.EventType.INITIATED );
        listener.transferInitiated( event.build() );
    }

    private void fireDone( Transfer transfer )
        throws Exception
    {
        TransferListener listener = transfer.getListener();
        if ( listener == null )
        {
            return;
        }
        TransferEvent.Builder event =
            new TransferEvent.Builder( session, new TransferResource( null, null, null, null, transfer.getTrace() ) );
        event.setException( transfer.getException() );
        if ( transfer.getException() != null )
        {
            listener.transferFailed( event.setType( TransferEvent.EventType.FAILED ).build() );
        }
        else
        {
            listener.transferSucceeded( event.setType( TransferEvent.EventType.SUCCEEDED ).build() );
        }
    }

    public void close()
    {
    }

    public void assertSeenExpected()
    {
        assertSeenExpected( actualGet, expectGet );
        assertSeenExpected( actualGetMD, expectGetMD );
        assertSeenExpected( actualPut, expectPut );
        assertSeenExpected( actualPutMD, expectPutMD );
    }

    private void assertSeenExpected( List<? extends Object> actual, Object[] expected )
    {
        if ( expected == null )
        {
            expected = new Object[0];
        }

        assertEquals( "different number of expected and actual elements:\n", expected.length, actual.size() );
        int idx = 0;
        for ( Object actualObject : actual )
        {
            assertEquals( "seen object differs", expected[idx++], actualObject );
        }
    }

    public List<Artifact> getActualArtifactGetRequests()
    {
        return actualGet;
    }

    public List<Metadata> getActualMetadataGetRequests()
    {
        return actualGetMD;
    }

    public List<Artifact> getActualArtifactPutRequests()
    {
        return actualPut;
    }

    public List<Metadata> getActualMetadataPutRequests()
    {
        return actualPutMD;
    }

    public void setExpectGet( Artifact... expectGet )
    {
        this.expectGet = expectGet;
    }

    public void setExpectPut( Artifact... expectPut )
    {
        this.expectPut = expectPut;
    }

    public void setExpectGet( Metadata... expectGetMD )
    {
        this.expectGetMD = expectGetMD;
    }

    public void setExpectPut( Metadata... expectPutMD )
    {
        this.expectPutMD = expectPutMD;
    }

    public void resetActual()
    {
        this.actualGet = new ArrayList<Artifact>();
        this.actualGetMD = new ArrayList<Metadata>();
        this.actualPut = new ArrayList<Artifact>();
        this.actualPutMD = new ArrayList<Metadata>();
    }

}
