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

#include "sal/main.h"
#include <osl/diagnose.h>
#include <osl/file.h>

#include <cppuhelper/bootstrap.hxx>

#include <com/sun/star/registry/XSimpleRegistry.hpp>

#define OUSTR(x) ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(x) )


using namespace ::rtl;
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;

static void print_options() SAL_THROW( () )
{
    printf(
        "\nusage: regsingleton [-r|-ra] registry_file singleton_name[=service_name] ...\n\n"
        "Inserts a singleton entry into rdb.\n"
        "Option -r revokes given entries, -ra revokes all entries.\n" );
}

//==================================================================================================
SAL_IMPLEMENT_MAIN_WITH_ARGS(argc, argv)
{
    if (argc < 3)
    {
        print_options();
        return 1;
    }

    bool insert_entry = true;
    bool remove_all = false;
    int nPos = 1;
    if ('-' == argv[ nPos ][ 0 ] && 'r' == argv[ nPos ][ 1 ])
    {
        if ('a' == argv[ nPos ][ 2 ] && '\0' == argv[ nPos ][ 3 ])
        {
            remove_all = true;
        }
        else if ('\0' != argv[ nPos ][ 2 ])
        {
            print_options();
            return 1;
        }
        insert_entry = false;
        ++nPos;
    }

    OUString sys_path( OUString::createFromAscii( argv[ nPos ] ) );
    OUString file_url;
    oslFileError rc = osl_getFileURLFromSystemPath( sys_path.pData, &file_url.pData );
    if (osl_File_E_None != rc)
    {
        fprintf( stderr, "\nerror: cannot make file url out of %s\n", argv[ nPos ] );
        return 1;
    }
    ++nPos;

	try
	{
        Reference< registry::XSimpleRegistry > xSimReg( ::cppu::createSimpleRegistry() );
        xSimReg->open( file_url, sal_False, sal_True );
        Reference< registry::XRegistryKey > xRoot( xSimReg->getRootKey() );

        if (remove_all)
        {
            try
            {
                xRoot->deleteKey( OUSTR("SINGLETONS") );
            }
            catch (registry::InvalidRegistryException & exc)
            {
                OString cstr_msg(
                    OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
                fprintf(
                    stderr, "\nwarning: removing all singletons failed: %s\n",
                    cstr_msg.getStr() );
            }
        }
        else
        {
            Reference< registry::XRegistryKey > xKey( xRoot->openKey( OUSTR("SINGLETONS") ) );
            if (! xKey.is())
                xKey = xRoot->createKey( OUSTR("SINGLETONS") );

            for ( ; nPos < argc; ++nPos )
            {
                OUString singleton( OUString::createFromAscii( argv[ nPos ] ) );
                OUString service;
                sal_Int32 eq = singleton.indexOf( '=' );
                if (eq >= 0)
                {
                    service = singleton.copy( eq +1 );
                    singleton = singleton.copy( 0, eq );
                }

                if (insert_entry)
                {
                    if (service.getLength())
                    {
                        Reference< registry::XRegistryKey > xEntry( xKey->openKey( singleton ) );
                        if (! xEntry.is())
                            xEntry = xKey->createKey( singleton );
                        xEntry->setStringValue( service );
                    }
                    else
                    {
                        OString entry( OUStringToOString( singleton, RTL_TEXTENCODING_ASCII_US ) );
                        fprintf(
                            stderr, "\nwarning: no service name given for singleton %s!\n",
                            entry.getStr() );
                    }
                }
                else
                {
                    try
                    {
                        xKey->deleteKey( singleton );
                    }
                    catch (registry::InvalidRegistryException & exc)
                    {
                        OString cstr_singleton(
                            OUStringToOString( singleton, RTL_TEXTENCODING_ASCII_US ) );
                        OString cstr_msg(
                            OUStringToOString( exc.Message, RTL_TEXTENCODING_ASCII_US ) );
                        fprintf(
                            stderr, "\nwarning: singleton %s is not registered: %s\n",
                            cstr_singleton.getStr(), cstr_msg.getStr() );
                    }
                }
            }
        }

        return 0;
	}
	catch (Exception & rExc)
	{
		OString msg( OUStringToOString( rExc.Message, RTL_TEXTENCODING_ASCII_US ) );
        fprintf( stderr, "\nerror: %s\n", msg.getStr() );
        return 1;
	}
}
