package org.apache.maven.plugin.assembly.utils;

/*
 * 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 org.apache.maven.plugin.assembly.format.AssemblyFormattingException;
import org.codehaus.plexus.logging.Logger;

import java.util.List;

/**
 * @version $Id$
 */
public final class TypeConversionUtils
{

    private static final int U_R = 256;

    private static final int U_W = 128;

    private static final int U_X = 64;

    private static final int G_R = 32;

    private static final int G_W = 16;

    private static final int G_X = 8;

    private static final int W_R = 4;

    private static final int W_W = 2;

    private static final int W_X = 1;

    private TypeConversionUtils()
    {
    }

    public static String[] toStringArray( final List<String> list )
    {
        String[] result = null;

        if ( ( list != null ) && !list.isEmpty() )
        {
            result = list.toArray( new String[list.size()] );
        }

        return result;
    }

    public static int modeToInt( final String mode, final Logger logger )
        throws AssemblyFormattingException
    {
        if ( mode == null || mode.trim().length() < 1 )
        {
            return -1;
        }

        try
        {
            final int value = Integer.parseInt( mode, 8 );

            // discard sanity assessment here; we're pushing ahead.
            verifyModeSanity( value, logger );

            return value;
        }
        catch ( final NumberFormatException e )
        {
            throw new AssemblyFormattingException( "Failed to parse mode as an octal number: \'" + mode + "\'.", e );
        }
    }

    // the boolean return type is for people who want to make a decision based on the sanity
    // assessment.
    public static boolean verifyModeSanity( final int mode, final Logger logger )
    {
        final StringBuilder messages = new StringBuilder();

        messages.append( "The mode: " ).append( Integer.toString( mode, 8 ) ).append( " contains nonsensical permissions:" );

        boolean warn = false;

        // read-access checks.
        if ( ( ( mode & U_R ) == 0 ) && ( ( mode & G_R ) == G_R ) )
        {
            messages.append( "\n- Group has read access, but user does not." );
            warn = true;
        }

        if ( ( ( mode & U_R ) == 0 ) && ( ( mode & W_R ) == W_R ) )
        {
            messages.append( "\n- World has read access, but user does not." );
            warn = true;
        }

        if ( ( ( mode & G_R ) == 0 ) && ( ( mode & W_R ) == W_R ) )
        {
            messages.append( "\n- World has read access, but group does not." );
            warn = true;
        }
        // end read-access checks.

        // write-access checks.
        if ( ( ( mode & U_W ) == 0 ) && ( ( mode & G_W ) == G_W ) )
        {
            messages.append( "\n- Group has write access, but user does not." );
            warn = true;
        }

        if ( ( ( mode & U_W ) == 0 ) && ( ( mode & W_W ) == W_W ) )
        {
            messages.append( "\n- World has write access, but user does not." );
            warn = true;
        }

        if ( ( ( mode & G_W ) == 0 ) && ( ( mode & W_W ) == W_W ) )
        {
            messages.append( "\n- World has write access, but group does not." );
            warn = true;
        }
        // end write-access checks.

        // execute-/list-access checks.
        if ( ( ( mode & U_X ) == 0 ) && ( ( mode & G_X ) == G_X ) )
        {
            messages.append( "\n- Group has execute/list access, but user does not." );
            warn = true;
        }

        if ( ( ( mode & U_X ) == 0 ) && ( ( mode & W_X ) == W_X ) )
        {
            messages.append( "\n- World has execute/list access, but user does not." );
            warn = true;
        }

        if ( ( ( mode & G_X ) == 0 ) && ( ( mode & W_X ) == W_X ) )
        {
            messages.append( "\n- World has execute/list access, but group does not." );
            warn = true;
        }
        // end execute-/list-access checks.

        if ( warn )
        {
            logger.warn( messages.toString() );
        }

        return !warn;
    }

}
