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

import java.util.List;

/**
 *
 */
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;
    }

}
