package org.apache.maven.shared.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 java.util.Collections;
import java.util.HashSet;
import java.util.Locale;
import java.util.Set;

/**
 * <p>Condition that tests the OS type.</p>
 * <p/>
 * <p>This class got copied over from Apache ANT.
 * Even the version from plexus-utils was
 * only an ANT fork!<br/>
 * The last time it got copied was on 2011-08-12</p>
 * <p/>
 * <p>When merging changes please take care of the special
 * OS_FAMILY handling in this version of Os.java!</p>
 *
 * @author Stefan Bodewig
 * @author Magesh Umasankar
 * @author Brian Fox
 * @author Mark Struberg
 * @version $Revision$
 * 
 */
public class Os
{
    /**
     * The OS Name.
     */
    public static final String OS_NAME = System.getProperty( "os.name" ).toLowerCase( Locale.ENGLISH );

    /**
     * The OA architecture.
     */
    public static final String OS_ARCH = System.getProperty( "os.arch" ).toLowerCase( Locale.ENGLISH );

    /**
     * The OS version.
     */
    public static final String OS_VERSION = System.getProperty( "os.version" ).toLowerCase( Locale.ENGLISH );

    /**
     * The path separator.
     */
    public static final String PATH_SEP = System.getProperty( "path.separator" );

    /**
     * system line separator , e.g. &quot;\n&quot; on unixoid systems and &quot;\r\n&quot; on Windows
     */
    public static final String LINE_SEP = System.getProperty( "line.separator" );

    /**
     * OS Family
     */
    public static final String OS_FAMILY = getOsFamily();

    // store the valid families
    private static final Set<String> VALID_FAMILIES = getValidFamilies();


    /**
     * OS family to look for
     */
    private String family;

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_WINDOWS = "windows";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_WIN9X = "win9x";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_NT = "winnt";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_OS2 = "os/2";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_NETWARE = "netware";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_DOS = "dos";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_MAC = "mac";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_TANDEM = "tandem";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_UNIX = "unix";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_OPENVMS = "openvms";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_ZOS = "z/os";

    /**
     * OS family that can be tested for. {@value}
     */
    public static final String FAMILY_OS400 = "os/400";

    /**
     * OpenJDK is reported to call MacOS X "Darwin"
     *
     * @see <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=44889">bugzilla issue</a>
     * @see <a href="https://issues.apache.org/jira/browse/HADOOP-3318">HADOOP-3318</a>
     */
    private static final String DARWIN = "darwin";


    /**
     * The set of valid families. This methods initializes the set until
     * VALID_FAMILIES constant is set.
     * @return The set of families.
     */
    public static Set<String> getValidFamilies()
    {
        if ( VALID_FAMILIES != null )
        {
            return VALID_FAMILIES;
        }

        Set<String> valid = new HashSet<String>();
        valid.add( FAMILY_DOS );
        valid.add( FAMILY_MAC );
        valid.add( FAMILY_NETWARE );
        valid.add( FAMILY_NT );
        valid.add( FAMILY_OPENVMS );
        valid.add( FAMILY_OS2 );
        valid.add( FAMILY_OS400 );
        valid.add( FAMILY_TANDEM );
        valid.add( FAMILY_UNIX );
        valid.add( FAMILY_WIN9X );
        valid.add( FAMILY_WINDOWS );
        valid.add( FAMILY_ZOS );

        return Collections.unmodifiableSet( valid );
    }

    /**
     * Default constructor
     */
    public Os()
    {
        //default
    }

    /**
     * Constructor that sets the family attribute
     *
     * @param family a String value
     */
    public Os( String family )
    {
        setFamily( family );
    }

    /**
     * Sets the desired OS family type
     *
     * @param f The OS family type desired<br />
     *          Possible values:<br />
     *          <ul>
     *          <li>dos</li>
     *          <li>mac</li>
     *          <li>netware</li>
     *          <li>os/2</li>
     *          <li>tandem</li>
     *          <li>unix</li>
     *          <li>windows</li>
     *          <li>win9x</li>
     *          <li>z/os</li>
     *          <li>os/400</li>
     *          </ul>
     */
    private void setFamily( String f )
    {
        family = f.toLowerCase( Locale.ENGLISH );
    }

    /**
     * Determines if the OS on which Ant is executing matches the type of
     * that set in setFamily.
     *
     * @return true if the os matches.
     * @see Os#setFamily(String)
     */
    boolean eval()
    {
        return isOs( family, null, null, null );
    }

    /**
     * Determines if the OS on which Ant is executing matches the
     * given OS family.
     *
     * @param family the family to check for
     * @return true if the OS matches
     * 
     */
    public static boolean isFamily( String family )
    {
        return isOs( family, null, null, null );
    }

    /**
     * Determines if the OS on which Ant is executing matches the
     * given OS name.
     *
     * @param name the OS name to check for
     * @return true if the OS matches
     * 
     */
    public static boolean isName( String name )
    {
        return isOs( null, name, null, null );
    }

    /**
     * Determines if the OS on which Ant is executing matches the
     * given OS architecture.
     *
     * @param arch the OS architecture to check for
     * @return true if the OS matches
     * 
     */
    public static boolean isArch( String arch )
    {
        return isOs( null, null, arch, null );
    }

    /**
     * Determines if the OS on which Ant is executing matches the
     * given OS version.
     *
     * @param version the OS version to check for
     * @return true if the OS matches
     * 
     */
    public static boolean isVersion( String version )
    {
        return isOs( null, null, null, version );
    }

    /**
     * Determines if the OS on which Ant is executing matches the
     * given OS family, name, architecture and version
     *
     * @param family  The OS family
     * @param name    The OS name
     * @param arch    The OS architecture
     * @param version The OS version
     * @return true if the OS matches
     * 
     */
    private static boolean isOs( String family, String name, String arch, String version )
    {
        boolean retValue = false;

        if ( family != null || name != null || arch != null || version != null )
        {

            boolean isFamily = true;
            boolean isName = true;
            boolean isArch = true;
            boolean isVersion = true;

            if ( family != null )
            {

                //windows probing logic relies on the word 'windows' in
                //the OS
                boolean isWindows = OS_NAME.contains( FAMILY_WINDOWS );
                boolean is9x = false;
                boolean isNT = false;
                if ( isWindows )
                {
                    //there are only four 9x platforms that we look for
                    is9x =
                        ( OS_NAME.contains( "95" ) || OS_NAME.contains( "98" ) || OS_NAME.contains( "me" )
                            //wince isn't really 9x, but crippled enough to
                            //be a muchness. Ant doesnt run on CE, anyway.
                            || OS_NAME.contains( "ce" ) );
                    isNT = !is9x;
                }
                if ( family.equals( FAMILY_WINDOWS ) )
                {
                    isFamily = isWindows;
                }
                else if ( family.equals( FAMILY_WIN9X ) )
                {
                    isFamily = isWindows && is9x;
                }
                else if ( family.equals( FAMILY_NT ) )
                {
                    isFamily = isWindows && isNT;
                }
                else if ( family.equals( FAMILY_OS2 ) )
                {
                    isFamily = OS_NAME.contains( FAMILY_OS2 );
                }
                else if ( family.equals( FAMILY_NETWARE ) )
                {
                    isFamily = OS_NAME.contains( FAMILY_NETWARE );
                }
                else if ( family.equals( FAMILY_DOS ) )
                {
                    isFamily = PATH_SEP.equals( ";" ) && !isFamily( FAMILY_NETWARE );
                }
                else if ( family.equals( FAMILY_MAC ) )
                {
                    isFamily = OS_NAME.contains( FAMILY_MAC ) || OS_NAME.contains( DARWIN );
                }
                else if ( family.equals( FAMILY_TANDEM ) )
                {
                    isFamily = OS_NAME.contains( "nonstop_kernel" );
                }
                else if ( family.equals( FAMILY_UNIX ) )
                {
                    isFamily = PATH_SEP.equals( ":" ) && !isFamily( FAMILY_OPENVMS ) && ( !isFamily( FAMILY_MAC )
                        || OS_NAME.endsWith( "x" ) || OS_NAME.contains( DARWIN ) );
                }
                else if ( family.equals( FAMILY_ZOS ) )
                {
                    isFamily = OS_NAME.contains( FAMILY_ZOS ) || OS_NAME.contains( "os/390" );
                }
                else if ( family.equals( FAMILY_OS400 ) )
                {
                    isFamily = OS_NAME.contains( FAMILY_OS400 );
                }
                else if ( family.equals( FAMILY_OPENVMS ) )
                {
                    isFamily = OS_NAME.contains( FAMILY_OPENVMS );
                }
                else
                {
                    isFamily = OS_NAME.contains( family.toLowerCase( Locale.US ) );
                }
            }
            if ( name != null )
            {
                isName = name.equals( OS_NAME );
            }
            if ( arch != null )
            {
                isArch = arch.equals( OS_ARCH );
            }
            if ( version != null )
            {
                isVersion = version.equals( OS_VERSION );
            }
            retValue = isFamily && isName && isArch && isVersion;
        }
        return retValue;
    }

    /**
     * Helper method to determine the current OS family.
     *
     * @return name of current OS family.
     */
    private static String getOsFamily()
    {
        Set<String> families = getValidFamilies();

        for ( String fam : families )
        {
            if ( Os.isFamily( fam ) )
            {
                return fam;
            }
        }
        return null;
    }

    /**
     * Test if the given family String represents a valid Family
     *
     * @param family the os family
     * @return <code>true</code> if 'family' represents a valid OS-Family, <code>false</code> otherwise.
     */
    public static boolean isValidFamily( String family )
    {
        return VALID_FAMILIES.contains( family );
    }

}
