package org.apache.archiva.cli;

/*
 * 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 com.sampullara.cli.Args;
import com.sampullara.cli.Argument;
import org.apache.archiva.admin.model.beans.ManagedRepository;
import org.apache.archiva.consumers.ConsumerException;
import org.apache.archiva.consumers.InvalidRepositoryContentConsumer;
import org.apache.archiva.consumers.KnownRepositoryContentConsumer;
import org.apache.archiva.consumers.RepositoryContentConsumer;
import org.apache.archiva.converter.RepositoryConversionException;
import org.apache.archiva.converter.legacy.LegacyRepositoryConverter;
import org.apache.archiva.repository.scanner.RepositoryScanStatistics;
import org.apache.archiva.repository.scanner.RepositoryScanner;
import org.apache.archiva.repository.scanner.RepositoryScannerException;
import org.apache.commons.lang.StringUtils;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * ArchivaCli
 * <p/>
 * <p/>
 * TODO add back reading of archiva.xml from a given location
 */
public class ArchivaCli
{
    // ----------------------------------------------------------------------------
    // Properties controlling Repository conversion
    // ----------------------------------------------------------------------------

    public static final String SOURCE_REPO_PATH = "sourceRepositoryPath";

    public static final String TARGET_REPO_PATH = "targetRepositoryPath";

    public static final String BLACKLISTED_PATTERNS = "blacklistPatterns";

    public static final String POM_PROPERTIES = "/META-INF/maven/org.apache.archiva/archiva-cli/pom.properties";

    private static String getVersion()
        throws IOException
    {

        try (InputStream pomStream = ArchivaCli.class.getResourceAsStream( POM_PROPERTIES ))
        {
            if ( pomStream == null )
            {
                throw new IOException( "Failed to load " + POM_PROPERTIES );
            }
            Properties properties = new Properties();
            properties.load( pomStream );
            return properties.getProperty( "version" );
        }
    }

    private ClassPathXmlApplicationContext applicationContext;

    public ArchivaCli()
    {
        applicationContext =
            new ClassPathXmlApplicationContext( new String[]{ "classpath*:/META-INF/spring-context.xml" } );
    }

    public static void main( String[] args )
        throws Exception
    {
        Commands command = new Commands();

        try
        {
            Args.parse( command, args );
        }
        catch ( IllegalArgumentException e )
        {
            System.err.println( e.getMessage() );
            Args.usage( command );
            return;
        }

        ArchivaCli cli = new ArchivaCli();
        try
        {
            cli.execute( command );
        }
        finally
        {
            cli.destroy();
        }
    }

    private void destroy()
    {
        applicationContext.destroy();
    }

    private void execute( Commands command )
        throws Exception
    {
        if ( command.help )
        {
            Args.usage( command );
        }
        else if ( command.version )
        {
            System.out.print( "Version: " + getVersion() );
        }
        else if ( command.convert )
        {
            doConversion( command.properties );
        }
        else if ( command.scan )
        {
            if ( command.repository == null )
            {
                System.err.println( "The repository must be specified." );
                Args.usage( command );
                return;
            }

            doScan( command.repository, command.consumers.split( "," ) );
        }
        else if ( command.listConsumers )
        {
            dumpAvailableConsumers();
        }
        else
        {
            Args.usage( command );
        }
    }

    private void doScan( String path, String[] consumers )
        throws ConsumerException, MalformedURLException
    {
        ManagedRepository repo = new ManagedRepository();
        repo.setId( new File( path ).getName() );
        repo.setName( "Archiva CLI Provided Repo" );
        repo.setLocation( path );

        List<KnownRepositoryContentConsumer> knownConsumerList = new ArrayList<>();

        knownConsumerList.addAll( getConsumerList( consumers ) );

        List<InvalidRepositoryContentConsumer> invalidConsumerList = Collections.emptyList();

        List<String> ignoredContent = new ArrayList<>();
        ignoredContent.addAll( Arrays.asList( RepositoryScanner.IGNORABLE_CONTENT ) );

        RepositoryScanner scanner = applicationContext.getBean( RepositoryScanner.class );

        try
        {
            RepositoryScanStatistics stats = scanner.scan( repo, knownConsumerList, invalidConsumerList, ignoredContent,
                                                           RepositoryScanner.FRESH_SCAN );

            System.out.println( "\n" + stats.toDump( repo ) );
        }
        catch ( RepositoryScannerException e )
        {
            e.printStackTrace( System.err );
        }
    }

    private List<KnownRepositoryContentConsumer> getConsumerList( String[] consumers )
        throws ConsumerException
    {
        List<KnownRepositoryContentConsumer> consumerList = new ArrayList<>();

        Map<String, KnownRepositoryContentConsumer> availableConsumers = getConsumers();

        for ( String specifiedConsumer : consumers )
        {
            if ( !availableConsumers.containsKey( specifiedConsumer ) )
            {
                System.err.println( "Specified consumer [" + specifiedConsumer + "] not found." );
                dumpAvailableConsumers();
                System.exit( 1 );
            }

            consumerList.add( availableConsumers.get( specifiedConsumer ) );
        }

        return consumerList;
    }

    private void dumpAvailableConsumers()
    {
        Map<String, KnownRepositoryContentConsumer> availableConsumers = getConsumers();

        System.out.println( ".\\ Available Consumer List \\.______________________________" );

        for ( Map.Entry<String, KnownRepositoryContentConsumer> entry : availableConsumers.entrySet() )
        {
            String consumerHint = entry.getKey();
            RepositoryContentConsumer consumer = entry.getValue();
            System.out.println(
                "  " + consumerHint + ": " + consumer.getDescription() + " (" + consumer.getClass().getName() + ")" );
        }
    }

    @SuppressWarnings( "unchecked" )
    private Map<String, KnownRepositoryContentConsumer> getConsumers()
    {
        Map<String, KnownRepositoryContentConsumer> beans =
            applicationContext.getBeansOfType( KnownRepositoryContentConsumer.class );
        // we use a naming conventions knownRepositoryContentConsumer#hint
        // with plexus we used only hint so remove before#

        Map<String, KnownRepositoryContentConsumer> smallNames = new HashMap<>( beans.size() );

        for ( Map.Entry<String, KnownRepositoryContentConsumer> entry : beans.entrySet() )
        {
            smallNames.put( StringUtils.substringAfterLast( entry.getKey(), "#" ), entry.getValue() );
        }

        return smallNames;
    }

    private void doConversion( String properties )
        throws IOException, RepositoryConversionException
    {
        LegacyRepositoryConverter legacyRepositoryConverter = applicationContext.getBean( LegacyRepositoryConverter.class );

        Properties p = new Properties();

        try (InputStream fis = Files.newInputStream( Paths.get(properties)))
        {
            p.load( fis );
        }

        File oldRepositoryPath = new File( p.getProperty( SOURCE_REPO_PATH ) );

        File newRepositoryPath = new File( p.getProperty( TARGET_REPO_PATH ) );

        System.out.println( "Converting " + oldRepositoryPath + " to " + newRepositoryPath );

        List<String> fileExclusionPatterns = null;

        String s = p.getProperty( BLACKLISTED_PATTERNS );

        if ( s != null )
        {
            fileExclusionPatterns = Arrays.asList( StringUtils.split( s, "," ) );
        }

        legacyRepositoryConverter.convertLegacyRepository( oldRepositoryPath, newRepositoryPath,
                                                           fileExclusionPatterns );
    }

    private static class Commands
    {
        @Argument( description = "Display help information", value = "help", alias = "h" )
        private boolean help;

        @Argument( description = "Display version information", value = "version", alias = "v" )
        private boolean version;

        @Argument( description = "List available consumers", value = "listconsumers", alias = "l" )
        private boolean listConsumers;

        @Argument( description = "The consumers to use (comma delimited)", value = "consumers", alias = "u" )
        private String consumers = "count-artifacts";

        @Argument( description = "Scan the specified repository", value = "scan", alias = "s" )
        private boolean scan;

        @Argument(
            description = "Convert a legacy Maven 1.x repository to a Maven 2.x repository using a properties file to describe the conversion",
            value = "convert", alias = "c" )
        private boolean convert;

        @Argument( description = "The properties file for the conversion", value = "properties" )
        private String properties = "conversion.properties";

        @Argument( description = "The repository to scan", value = "repository" )
        private String repository;
    }
}
