package org.apache.maven.archiva.web.action;

/*
 * 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.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Collections;
import java.util.List;
import java.util.TimeZone;

import org.apache.archiva.checksum.ChecksumAlgorithm;
import org.apache.archiva.checksum.ChecksummedFile;
import org.apache.maven.archiva.common.utils.VersionComparator;
import org.apache.maven.archiva.common.utils.VersionUtil;
import org.apache.maven.archiva.configuration.ArchivaConfiguration;
import org.apache.maven.archiva.configuration.ManagedRepositoryConfiguration;
import org.apache.maven.archiva.model.ArchivaProjectModel;
import org.apache.maven.archiva.model.ArchivaRepositoryMetadata;
import org.apache.maven.archiva.model.ArtifactReference;
import org.apache.maven.archiva.model.SnapshotVersion;
import org.apache.maven.archiva.repository.ManagedRepositoryContent;
import org.apache.maven.archiva.repository.RepositoryContentFactory;
import org.apache.maven.archiva.repository.RepositoryException;
import org.apache.maven.archiva.repository.RepositoryNotFoundException;
import org.apache.maven.archiva.repository.scanner.RepositoryContentConsumers;
import org.apache.maven.archiva.repository.audit.AuditEvent;
import org.apache.maven.archiva.repository.audit.AuditListener;
import org.apache.maven.archiva.repository.audit.Auditable;
import org.apache.maven.archiva.repository.metadata.MetadataTools;
import org.apache.maven.archiva.repository.metadata.RepositoryMetadataException;
import org.apache.maven.archiva.repository.metadata.RepositoryMetadataReader;
import org.apache.maven.archiva.repository.metadata.RepositoryMetadataWriter;
import org.apache.maven.archiva.repository.project.ProjectModelException;
import org.apache.maven.archiva.repository.project.ProjectModelWriter;
import org.apache.maven.archiva.repository.project.writers.ProjectModel400Writer;
import org.apache.maven.archiva.security.ArchivaSecurityException;
import org.apache.maven.archiva.security.PrincipalNotFoundException;
import org.apache.maven.archiva.security.UserRepositories;
import org.apache.maven.archiva.security.ArchivaXworkUser;

import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.Preparable;
import com.opensymphony.xwork2.Validateable;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang.StringUtils;

/**
 * Upload an artifact using Jakarta file upload in webwork. If set by the user a pom will also be generated. Metadata
 * will also be updated if one exists, otherwise it would be created.
 * 
 * @author <a href="mailto:wsmoak@apache.org">Wendy Smoak</a>
 * @author <a href="mailto:oching@apache.org">Maria Odea Ching</a>
 * @plexus.component role="com.opensymphony.xwork2.Action" role-hint="uploadAction"
 */
public class UploadAction
    extends PlexusActionSupport
    implements Validateable, Preparable, Auditable
{
    /**
      * @plexus.requirement
      */
     private RepositoryContentConsumers consumers;
     
     /**
      * @plexus.requirement
      */
     private ArchivaXworkUser archivaXworkUser;
    
    /**
     * The groupId of the artifact to be deployed.
     */
    private String groupId;

    /**
     * The artifactId of the artifact to be deployed.
     */
    private String artifactId;

    /**
     * The version of the artifact to be deployed.
     */
    private String version;

    /**
     * The packaging of the artifact to be deployed.
     */
    private String packaging;

    /**
     * The classifier of the artifact to be deployed.
     */
    private String classifier;

    /**
     * The temporary file representing the artifact to be deployed.
     */
    private File artifactFile;

    /**
     * The content type of the artifact to be deployed.
     */
    private String artifactContentType;

    /**
     * The original filename of the uploaded artifact file.
     */
    private String artifactFilename;

    /**
     * The temporary file representing the pom to be deployed alongside the artifact.
     */
    private File pomFile;

    /**
     * The content type of the pom file.
     */
    private String pomContentType;

    /**
     * The original filename of the uploaded pom file.
     */
    private String pomFilename;

    /**
     * The repository where the artifact is to be deployed.
     */
    private String repositoryId;

    /**
     * Flag whether to generate a pom for the artifact or not.
     */
    private boolean generatePom;

    /**
     * List of managed repositories to deploy to.
     */
    private List<String> managedRepoIdList;

    /**
     * @plexus.requirement
     */
    private UserRepositories userRepositories;

    /**
     * @plexus.requirement role-hint="default"
     */
    private ArchivaConfiguration configuration;

    /**
     * @plexus.requirement
     */
    private RepositoryContentFactory repositoryFactory;
    
    /**
     * @plexus.requirement role="org.apache.maven.archiva.repository.audit.AuditListener"
     */
    private List<AuditListener> auditListeners = new ArrayList<AuditListener>();
    
    private ChecksumAlgorithm[] algorithms = new ChecksumAlgorithm[] { ChecksumAlgorithm.SHA1, ChecksumAlgorithm.MD5 };

    private ProjectModelWriter pomWriter = new ProjectModel400Writer();
    
    public void setArtifact( File file )
    {
        this.artifactFile = file;
    }

    public void setArtifactContentType( String contentType )
    {
        this.artifactContentType = contentType;
    }

    public void setArtifactFileName( String filename )
    {
        this.artifactFilename = filename;
    }

    public void setPom( File file )
    {
        this.pomFile = file;
    }

    public void setPomContentType( String contentType )
    {
        this.pomContentType = contentType;
    }

    public void setPomFileName( String filename )
    {
        this.pomFilename = filename;
    }

    public String getGroupId()
    {
        return groupId;
    }

    public void setGroupId( String groupId )
    {
        this.groupId = groupId;
    }

    public String getArtifactId()
    {
        return artifactId;
    }

    public void setArtifactId( String artifactId )
    {
        this.artifactId = artifactId;
    }

    public String getVersion()
    {
        return version;
    }

    public void setVersion( String version )
    {
        this.version = version;
    }

    public String getPackaging()
    {
        return packaging;
    }

    public void setPackaging( String packaging )
    {
        this.packaging = packaging;
    }

    public String getClassifier()
    {
        return classifier;
    }

    public void setClassifier( String classifier )
    {
        this.classifier = classifier;
    }

    public String getRepositoryId()
    {
        return repositoryId;
    }

    public void setRepositoryId( String repositoryId )
    {
        this.repositoryId = repositoryId;
    }

    public boolean isGeneratePom()
    {
        return generatePom;
    }

    public void setGeneratePom( boolean generatePom )
    {
        this.generatePom = generatePom;
    }

    public List<String> getManagedRepoIdList()
    {
        return managedRepoIdList;
    }

    public void setManagedRepoIdList( List<String> managedRepoIdList )
    {
        this.managedRepoIdList = managedRepoIdList;
    }

    public void prepare()
    {
        managedRepoIdList =
            new ArrayList<String>( configuration.getConfiguration().getManagedRepositoriesAsMap().keySet() );
    }

    public String input()
    {
        return INPUT;
    }

    private void reset()
    {
        // reset the fields so the form is clear when 
        // the action returns to the jsp page
        groupId = "";
        artifactId = "";
        version = "";
        packaging = "";
        classifier = "";
        artifactFile = null;
        artifactContentType = "";
        artifactFilename = "";
        pomFile = null;
        pomContentType = "";
        pomFilename = "";
        repositoryId = "";
        generatePom = false;
    }
    
    public String doUpload()
    {
        try
        {
            ManagedRepositoryConfiguration repoConfig =
                configuration.getConfiguration().findManagedRepositoryById( repositoryId );

            ArtifactReference artifactReference = new ArtifactReference();
            artifactReference.setArtifactId( artifactId );
            artifactReference.setGroupId( groupId );
            artifactReference.setVersion( version );
            artifactReference.setClassifier( classifier );
            artifactReference.setType( packaging );

            ManagedRepositoryContent repository = repositoryFactory.getManagedRepositoryContent( repositoryId );

            String artifactPath = repository.toPath( artifactReference );

            int lastIndex = artifactPath.lastIndexOf( '/' );

            File targetPath = new File( repoConfig.getLocation(), artifactPath.substring( 0, lastIndex ) );

            Date lastUpdatedTimestamp = Calendar.getInstance().getTime();
            int newBuildNumber = -1;
            String timestamp = null;
            
            File metadataFile = getMetadata( targetPath.getAbsolutePath() );
            ArchivaRepositoryMetadata metadata = getMetadata( metadataFile );

            if (VersionUtil.isSnapshot(version))
            {
                TimeZone timezone = TimeZone.getTimeZone( "UTC" );
                DateFormat fmt = new SimpleDateFormat( "yyyyMMdd.HHmmss" );
                fmt.setTimeZone( timezone );
                timestamp = fmt.format( lastUpdatedTimestamp );
                if ( metadata.getSnapshotVersion() != null )
                {
                    newBuildNumber = metadata.getSnapshotVersion().getBuildNumber() + 1;
                }
                else
                {
                	metadata.setSnapshotVersion( new SnapshotVersion() );
                	newBuildNumber = 1;
                }
            }

            if ( !targetPath.exists() )
            {
                targetPath.mkdirs();
            }

            String filename = artifactPath.substring( lastIndex + 1 );
            if ( VersionUtil.isSnapshot( version ) )
            {
                filename = filename.replaceAll( "SNAPSHOT", timestamp + "-" + newBuildNumber );
            }

            try
            {
                copyFile( artifactFile, targetPath, filename );
                consumers.executeConsumers( repoConfig, repository.toFile( artifactReference ) );
            }
            catch ( IOException ie )
            {
                addActionError( "Error encountered while uploading file: " + ie.getMessage() );
                return ERROR;
            }

            String pomFilename = filename;
            if( classifier != null && !"".equals( classifier ) )
            {
                pomFilename = StringUtils.remove( pomFilename, "-" + classifier );
            }
            pomFilename = FilenameUtils.removeExtension( pomFilename ) + ".pom";
                
            if ( generatePom )
            {
                try
                {
                    File generatedPomFile = createPom( targetPath, pomFilename );
                    consumers.executeConsumers( repoConfig, generatedPomFile );
                }
                catch ( IOException ie )
                {
                    addActionError( "Error encountered while writing pom file: " + ie.getMessage() );
                    return ERROR;
                }
                catch ( ProjectModelException pe )
                {
                    addActionError( "Error encountered while generating pom file: " + pe.getMessage() );
                    return ERROR;
                }
            }
            
            if ( pomFile != null && pomFile.length() > 0 ) 
            {
                try
                {                    
                    copyFile( pomFile, targetPath, pomFilename );
                    consumers.executeConsumers( repoConfig, new File( targetPath, pomFilename ) );
                }
                catch ( IOException ie )
                {
                    addActionError( "Error encountered while uploading pom file: " + ie.getMessage() );
                    return ERROR;
                }
                
            }

            updateMetadata( metadata, metadataFile, lastUpdatedTimestamp, timestamp, newBuildNumber );

            String msg = "Artifact \'" + groupId + ":" + artifactId + ":" + version +
                "\' was successfully deployed to repository \'" + repositoryId + "\'";
                        
            triggerAuditEvent( getPrincipal(), repositoryId, groupId + ":" + artifactId + ":" + version, AuditEvent.UPLOAD_FILE );
            
            addActionMessage( msg );

            reset();
            return SUCCESS;
        }
        catch ( RepositoryNotFoundException re )
        {
            addActionError( "Target repository cannot be found: " + re.getMessage() );
            return ERROR;
        }
        catch ( RepositoryException rep )
        {
            addActionError( "Repository exception: " + rep.getMessage() );
            return ERROR;
        }
    }

    private String getPrincipal()
    {
        return archivaXworkUser.getActivePrincipal( ActionContext.getContext().getSession() );
    }

    private void copyFile( File sourceFile, File targetPath, String targetFilename )
        throws IOException
    {
        FileOutputStream out = new FileOutputStream( new File( targetPath, targetFilename ) );

        try
        {
            FileInputStream input = new FileInputStream( sourceFile );
            int i = 0;
            while ( ( i = input.read() ) != -1 )
            {
                out.write( i );
            }
            out.flush();
        }
        finally
        {
            out.close();
        }
    }

    private File createPom( File targetPath, String filename )
        throws IOException, ProjectModelException
    {
        ArchivaProjectModel projectModel = new ArchivaProjectModel();
        projectModel.setGroupId( groupId );
        projectModel.setArtifactId( artifactId );
        projectModel.setVersion( version );
        projectModel.setPackaging( packaging );
        
        File pomFile = new File( targetPath, filename);        
        pomWriter.write( projectModel, pomFile );

        return pomFile;
    }

    private File getMetadata( String targetPath )
    {
        String artifactPath = targetPath.substring( 0, targetPath.lastIndexOf( File.separatorChar ) );

        return new File( artifactPath, MetadataTools.MAVEN_METADATA );
    }

    private ArchivaRepositoryMetadata getMetadata( File metadataFile )
        throws RepositoryMetadataException
    {
        ArchivaRepositoryMetadata metadata = new ArchivaRepositoryMetadata();
        if ( metadataFile.exists() )
        {
            metadata = RepositoryMetadataReader.read( metadataFile );
        }
        return metadata;
    }

    /**
     * Update artifact level metadata. If it does not exist, create the metadata.
     * 
     * @param metadata
     */
    private void updateMetadata( ArchivaRepositoryMetadata metadata, File metadataFile, Date lastUpdatedTimestamp,
                                 String timestamp, int buildNumber )
        throws RepositoryMetadataException
    {
        List<String> availableVersions = new ArrayList<String>();
        String latestVersion = version;

        if ( metadataFile.exists() )
        {
            availableVersions = metadata.getAvailableVersions();

            Collections.sort( availableVersions, VersionComparator.getInstance() );

            if ( !availableVersions.contains( version ) )
            {
                availableVersions.add( version );
            }

            latestVersion = availableVersions.get( availableVersions.size() - 1 );
        }
        else
        {
            availableVersions.add( version );

            metadata.setGroupId( groupId );
            metadata.setArtifactId( artifactId );
        }

        if ( metadata.getGroupId() == null )
        {
        	metadata.setGroupId( groupId );
        }
        if ( metadata.getArtifactId() == null )
        {
        	metadata.setArtifactId( artifactId );
        }

        metadata.setLatestVersion( latestVersion );
        metadata.setLastUpdatedTimestamp( lastUpdatedTimestamp );
        metadata.setAvailableVersions( availableVersions );

        if ( !VersionUtil.isSnapshot( version ) )
        {
            metadata.setReleasedVersion( latestVersion );
        }
        else
        {
            metadata.getSnapshotVersion().setBuildNumber( buildNumber );

            metadata.getSnapshotVersion().setTimestamp( timestamp );
        }

        RepositoryMetadataWriter.write( metadata, metadataFile );
        ChecksummedFile checksum = new ChecksummedFile( metadataFile );
        checksum.fixChecksums( algorithms );
    }

    public void validate()
    {
        try
        {
            // is this enough check for the repository permission?
            if ( !userRepositories.isAuthorizedToUploadArtifacts( getPrincipal(), repositoryId ) )
            {
                addActionError( "User is not authorized to upload in repository " + repositoryId );
            }

            if ( artifactFile == null || artifactFile.length() == 0 )
            {
                addActionError( "Please add a file to upload." );
            }
            
            if ( !VersionUtil.isVersion( version ) )
            {
                addActionError( "Invalid version." );
            }            
        }
        catch ( PrincipalNotFoundException pe )
        {
            addActionError( pe.getMessage() );
        }
        catch ( ArchivaSecurityException ae )
        {
            addActionError( ae.getMessage() );
        }
    }
    
    public void addAuditListener( AuditListener listener )
    {
        this.auditListeners.add( listener );
    }

    public void clearAuditListeners()
    {
        this.auditListeners.clear();
    }

    public void removeAuditListener( AuditListener listener )
    {
        this.auditListeners.remove( listener );
    }
    
    private void triggerAuditEvent( String user, String repositoryId, String resource, String action )
    {
        AuditEvent event = new AuditEvent( repositoryId, user, resource, action );
        event.setRemoteIP( ServletActionContext.getRequest().getRemoteAddr() );
        
        for ( AuditListener listener : auditListeners )
        {
            listener.auditEvent( event );
        }
    }
}
