/**************************************************************
 * 
 * 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.
 * 
 *************************************************************/



#include "precompiled_cppuhelper.hxx"
#include "sal/config.h"

#include <stdlib.h>
#include <string.h>

#if defined WNT

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

/*
 * Gets the installation path from the Windows Registry for the specified
 * registry key.
 *
 * @param hroot       open handle to predefined root registry key
 * @param subKeyName  name of the subkey to open
 *
 * @return the installation path or NULL, if no installation was found or
 *         if an error occured
 */
static char* getPathFromRegistryKey( HKEY hroot, const char* subKeyName )
{
    HKEY hkey;
    DWORD type;
    char* data = NULL;
    DWORD size;

    /* open the specified registry key */
    if ( RegOpenKeyEx( hroot, subKeyName, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
    {
        return NULL;
    }

    /* find the type and size of the default value */
    if ( RegQueryValueEx( hkey, NULL, NULL, &type, NULL, &size) != ERROR_SUCCESS )
    {
        RegCloseKey( hkey );
        return NULL;
    }

    /* get memory to hold the default value */
    data = (char*) malloc( size );

    /* read the default value */
    if ( RegQueryValueEx( hkey, NULL, NULL, &type, (LPBYTE) data, &size ) != ERROR_SUCCESS )
    {
        RegCloseKey( hkey );
        return NULL;
    }

    /* release registry key handle */
    RegCloseKey( hkey );

    return data;
}

/*
 * Gets the installation path from the Windows Registry.
 *
 * @return the installation path or NULL, if no installation was found or
 *         if an error occured
 */
static char* platformSpecific()
{
    const char* SUBKEYNAME = "Software\\OpenOffice\\UNO\\InstallPath";
    const char* SUBKEYNAME64 = "Software\\Wow6432Node\\OpenOffice\\UNO\\InstallPath";

    char* path = NULL;
    
    /* read the key's default value from HKEY_CURRENT_USER */
    path = getPathFromRegistryKey( HKEY_CURRENT_USER, SUBKEYNAME );

    if ( path == NULL )
    {
        /* read the key's default value from HKEY_LOCAL_USER 64 */
        path = getPathFromRegistryKey( HKEY_CURRENT_USER, SUBKEYNAME64 );
    }
    if ( path == NULL )
    {
        /* read the key's default value from HKEY_LOCAL_MACHINE */
        path = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, SUBKEYNAME );
    }
    if ( path == NULL )
    {
        /* read the key's default value from HKEY_LOCAL_MACHINE 64*/
        path = getPathFromRegistryKey( HKEY_LOCAL_MACHINE, SUBKEYNAME64 );
    }

    return path;
}

#else

#include <unistd.h>
#include <limits.h>
#include <stdio.h>
/*     
 * Gets the installation path from the PATH environment variable.
 *
 * <p>An installation is found, if the executable 'soffice' or a symbolic link
 * is in one of the directories listed in the PATH environment variable.</p>
 *
 * @return the installation path or NULL, if no installation was found or 
 *         if an error occured
 */
static char* platformSpecific()
{
    char* path = NULL;

#ifdef MACOSX
    /* On MacOS we have no soffice link under /usr/bin but the default office location is known
       and we check this only
     */
    const char* MACDEFAULTOFFICEPATH = "/Applications/OpenOffice.app/Contents/MacOS";
    const char* MACDEFAULTSOFFICE = "/Applications/OpenOffice.app/Contents/MacOS/soffice";

    if ( !access( MACDEFAULTSOFFICE, F_OK ) )
    {
        path = (char*) malloc( strlen(MACDEFAULTOFFICEPATH) + 1 );
        strcpy( path, MACDEFAULTOFFICEPATH);
    }
    return path;
#else
    const int SEPARATOR = '/';
    const char* PATHSEPARATOR = ":";
    const char* PATHVARNAME = "PATH";
    const char* APPENDIX = "/soffice";

    char* env = NULL;
    char* str = NULL;
    char* dir = NULL;
    char* file = NULL;
    char* resolved = NULL;
    char* sep = NULL;

    char buffer[PATH_MAX];
    int pos;

/* get the value of the PATH environment variable */
    env = getenv( PATHVARNAME );
	str = (char*) malloc( strlen( env ) + 1 );
	strcpy( str, env );

    /* get the tokens separated by ':' */
    dir = strtok( str, PATHSEPARATOR );

	while ( dir )
	{
        /* construct soffice file path */
        file = (char*) malloc( strlen( dir ) + strlen( APPENDIX ) + 1 );
		strcpy( file, dir );
		strcat( file, APPENDIX );

		/* check existence of soffice file */
		if ( !access( file, F_OK ) )
		{
            /* resolve symbolic link */
			resolved = realpath( file, buffer );

            if ( resolved != NULL )
			{
                /* get path to program directory */
				sep = strrchr( resolved, SEPARATOR );

				if ( sep != NULL )
				{
                    pos = sep - resolved;
                    path = (char*) malloc( pos + 1 );
                    strncpy( path, resolved, pos );
                    path[ pos ] = '\0';
                    free( file );
                    break;
				}
			}
		}

		dir = strtok( NULL, PATHSEPARATOR );
        free( file );
	}

	free( str );

    return path;
#endif
}

#endif

char const* cppuhelper_detail_findSofficePath()
{
    const char* UNOPATHVARNAME = "UNO_PATH";

    char* path = NULL;

    /* get the installation path from the UNO_PATH environment variable */
    path = getenv( UNOPATHVARNAME );

    if ( path == NULL || strlen( path ) == 0 )
    {
		path = platformSpecific();
    }

    return path;
}
