package org.apache.maven.plugin.coreit;

/*
 * 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.IOException;
import java.io.OutputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.nio.file.Files;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Properties;

/**
 * Assists in serializing primitives and beans into properties for later inspection/verification.
 *
 * @author Benjamin Bentmann
 *
 */
class PropertyUtil
{

    private static final Object[] NO_ARGS = {};

    private static final Class[] NO_PARAMS = {};

    /**
     * Serializes the specified object into the given properties, using the provided key. The object may be a scalar
     * value like a string or some array/collection/map or a bean.
     *
     * @param props The properties to serialize into, must not be <code>null</code>.
     * @param key   The key to use for serialization of the object data, must not be <code>null</code>.
     * @param obj   The object to serialize, may be <code>null</code>.
     */
    public static void store( Properties props, String key, Object obj )
    {
        store( props, key, obj, new HashSet() );
    }

    /**
     * Serializes the specified object into the given properties, using the provided key. The object may be a scalar
     * value like a string or some array/collection/map or a bean.
     *
     * @param props   The properties to serialize into, must not be <code>null</code>.
     * @param key     The key to use for serialization of the object data, must not be <code>null</code>.
     * @param obj     The object to serialize, may be <code>null</code>.
     * @param visited The set/stack of already visited objects, used to detect back references in the object graph, must
     *                not be <code>null</code>.
     */
    private static void store( Properties props, String key, Object obj, Collection visited )
    {
        if ( obj != null && !visited.contains( obj ) )
        {
            visited.add( obj );
            if ( ( obj instanceof String ) || ( obj instanceof Number ) || ( obj instanceof Boolean )
                || ( obj instanceof File ) )
            {
                props.put( key, obj.toString() );
            }
            else if ( obj instanceof Collection )
            {
                Collection coll = (Collection) obj;
                props.put( key, Integer.toString( coll.size() ) );
                int index = 0;
                for ( Iterator it = coll.iterator(); it.hasNext(); index++ )
                {
                    Object elem = it.next();
                    store( props, key + "." + index, elem, visited );
                }
            }
            else if ( obj instanceof Map )
            {
                Map map = (Map) obj;
                props.put( key, Integer.toString( map.size() ) );
                int index = 0;
                for ( Iterator it = map.entrySet().iterator(); it.hasNext(); index++ )
                {
                    Map.Entry entry = (Map.Entry) it.next();
                    store( props, key + "." + entry.getKey(), entry.getValue(), visited );
                }
            }
            else if ( obj.getClass().isArray() )
            {
                int length = Array.getLength( obj );
                props.put( key, Integer.toString( length ) );
                for ( int index = 0; index < length; index++ )
                {
                    Object elem = Array.get( obj, index );
                    store( props, key + "." + index, elem, visited );
                }
            }
            else if ( obj.getClass().getName().endsWith( "Xpp3Dom" ) )
            {
                Class type = obj.getClass();
                try
                {
                    Method getValue = type.getMethod( "getValue", NO_PARAMS );
                    String value = (String) getValue.invoke( obj, NO_ARGS );

                    if ( value != null )
                    {
                        props.put( key + ".value", value );
                    }

                    Method getName = type.getMethod( "getName", NO_PARAMS );

                    Method getChildren = type.getMethod( "getChildren", NO_PARAMS );
                    Object[] children = (Object[]) getChildren.invoke( obj, NO_ARGS );

                    props.put( key + ".children", Integer.toString( children.length ) );

                    Map indices = new HashMap();
                    for ( Object child : children )
                    {
                        String name = (String) getName.invoke( child, NO_ARGS );

                        Integer index = (Integer) indices.get( name );
                        if ( index == null )
                        {
                            index = 0;
                        }

                        store( props, key + ".children." + name + "." + index, child, visited );

                        indices.put( name, index + 1 );
                    }
                }
                catch ( Exception e )
                {
                    // can't happen
                }
            }
            else
            {
                Class type = obj.getClass();
                Method[] methods = type.getMethods();
                for ( Method method : methods )
                {
                    if ( Modifier.isStatic( method.getModifiers() ) || method.getParameterTypes().length > 0
                        || !method.getName().matches( "(get|is)\\p{Lu}.*" ) || method.getName().endsWith( "AsMap" )
                        || Class.class.isAssignableFrom( method.getReturnType() ) || Object.class.equals(
                        method.getReturnType() ) )
                    {
                        continue;
                    }

                    try
                    {
                        Object value = method.invoke( obj, NO_ARGS );
                        store( props, key + "." + getPropertyName( method.getName() ), value, visited );
                    }
                    catch ( Exception e )
                    {
                        // just ignore
                    }
                }
            }
            visited.remove( obj );
        }
    }

    /**
     * Derives the bean property name from the specified method for its getter.
     *
     * @param methodName The method name of the property's getter, must not be <code>null</code>.
     * @return The property name, never <code>null</code>.
     */
    static String getPropertyName( String methodName )
    {
        String propertyName = methodName;
        if ( methodName.startsWith( "get" ) && methodName.length() > 3 )
        {
            propertyName = Character.toLowerCase( methodName.charAt( 3 ) ) + methodName.substring( 4 );
        }
        else if ( methodName.startsWith( "is" ) && methodName.length() > 2 )
        {
            propertyName = Character.toLowerCase( methodName.charAt( 2 ) ) + methodName.substring( 3 );
        }
        return propertyName;
    }

    /**
     * Writes the specified properties to the given file.
     *
     * @param props The properties to write, must not be <code>null</code>.
     * @param file  The output file for the properties, must not be <code>null</code>.
     * @throws IOException If the properties could not be written to the file.
     */
    public static void write( Properties props, File file )
        throws IOException
    {
        file.getParentFile().mkdirs();

        try ( OutputStream out = Files.newOutputStream( file.toPath() ) )
        {
            props.store( out, "MAVEN-CORE-IT-LOG" );
        }
    }

}
