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



// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_scripting.hxx"

#include <com/sun/star/uri/XVndSunStarScriptUrl.hpp>
#include <rtl/ustrbuf.hxx>
#include "URIHelper.hxx"

#define PRTSTR(x) ::rtl::OUStringToOString(x, RTL_TEXTENCODING_ASCII_US).pData->buffer

namespace func_provider
{

using ::rtl::OUString;
namespace uno = ::com::sun::star::uno;
namespace ucb = ::com::sun::star::ucb;
namespace lang = ::com::sun::star::lang;
namespace uri = ::com::sun::star::uri;
namespace script = ::com::sun::star::script;
 
static const char SHARE[] = "share";
static const char SHARE_URI[] =
    "vnd.sun.star.expand:$$OOO_BASE_DIR";
//    "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::BaseInstallation}";

static const char SHARE_UNO_PACKAGES[] = "share:uno_packages";
static const char SHARE_UNO_PACKAGES_URI[] = 
    "vnd.sun.star.expand:$UNO_SHARED_PACKAGES_CACHE";

static const char USER[] = "user";
static const char USER_URI[] =
    "vnd.sun.star.expand:${$OOO_BASE_DIR/program/" SAL_CONFIGFILE( "bootstrap") "::UserInstallation}";

static const char USER_UNO_PACKAGES[] = "user:uno_packages";
static const char USER_UNO_PACKAGES_DIR[] =
    "/user/uno_packages/cache";

static const char DOCUMENT[] = "document";
static const char TDOC_SCHEME[] = "vnd.sun.star.tdoc";

ScriptingFrameworkURIHelper::ScriptingFrameworkURIHelper(
    const uno::Reference< uno::XComponentContext >& xContext)
        throw( uno::RuntimeException )
{
    try
    {
        m_xSimpleFileAccess = uno::Reference< ucb::XSimpleFileAccess >(
            xContext->getServiceManager()->createInstanceWithContext(
                OUString::createFromAscii(
                    "com.sun.star.ucb.SimpleFileAccess"),
                xContext), uno::UNO_QUERY_THROW);
    }
    catch (uno::Exception&)
    {
        OSL_ENSURE(false,
            "Scripting Framework error initialising XSimpleFileAccess");
    }

    try
    {
        m_xUriReferenceFactory = uno::Reference< uri::XUriReferenceFactory >(
            xContext->getServiceManager()->createInstanceWithContext(
                OUString::createFromAscii(
                    "com.sun.star.uri.UriReferenceFactory"),
            xContext ), uno::UNO_QUERY_THROW );
    }
    catch (uno::Exception&)
    {
        OSL_ENSURE(false,
            "Scripting Framework error initialising XUriReferenceFactory");
    }
}

ScriptingFrameworkURIHelper::~ScriptingFrameworkURIHelper()
{
    // currently does nothing
}

void SAL_CALL
ScriptingFrameworkURIHelper::initialize(
    const uno::Sequence < uno::Any >& args )
throw ( uno::Exception, uno::RuntimeException )
{
    if ( args.getLength() != 2 ||
         args[0].getValueType() != ::getCppuType((const OUString*)NULL) || 
         args[1].getValueType() != ::getCppuType((const OUString*)NULL) )
    {
        throw uno::RuntimeException( OUString::createFromAscii(
            "ScriptingFrameworkURIHelper got invalid argument list" ),
                uno::Reference< uno::XInterface >() );
    }

    if ( (args[0] >>= m_sLanguage) == sal_False ||
         (args[1] >>= m_sLocation) == sal_False )
    {
        throw uno::RuntimeException( OUString::createFromAscii(
            "ScriptingFrameworkURIHelper error parsing args" ),
                uno::Reference< uno::XInterface >() );
    }

    SCRIPTS_PART = OUString::createFromAscii( "/Scripts/" );
    SCRIPTS_PART = SCRIPTS_PART.concat( m_sLanguage.toAsciiLowerCase() );

    if ( !initBaseURI() )
    {
        throw uno::RuntimeException( OUString::createFromAscii(
            "ScriptingFrameworkURIHelper cannot find script directory"),
                uno::Reference< uno::XInterface >() );
    }
}

bool
ScriptingFrameworkURIHelper::initBaseURI()
{
    OUString uri, test;
    bool bAppendScriptsPart = false;

    if ( m_sLocation.equalsAscii(USER))
    {
        test = OUString::createFromAscii(USER);
        uri = OUString::createFromAscii(USER_URI);
        bAppendScriptsPart = true;
    }
    else if ( m_sLocation.equalsAscii(USER_UNO_PACKAGES))
    {
        test = OUString::createFromAscii("uno_packages");
        uri = OUString::createFromAscii(USER_URI);
        uri = uri.concat(OUString::createFromAscii(USER_UNO_PACKAGES_DIR));
    }
    else if (m_sLocation.equalsAscii(SHARE))
    {
        test = OUString::createFromAscii(SHARE);
        uri = OUString::createFromAscii(SHARE_URI);
        bAppendScriptsPart = true;
    }
    else if (m_sLocation.equalsAscii(SHARE_UNO_PACKAGES))
    {
        test = OUString::createFromAscii("uno_packages");
        uri = OUString::createFromAscii(SHARE_UNO_PACKAGES_URI);
    }
    else if (m_sLocation.indexOf(OUString::createFromAscii(TDOC_SCHEME)) == 0)
    {
        m_sBaseURI = m_sLocation.concat( SCRIPTS_PART );
        m_sLocation = OUString::createFromAscii( DOCUMENT );
        return true;
    }
    else
    {
        return false;
    }

    if ( !m_xSimpleFileAccess->exists( uri ) ||
         !m_xSimpleFileAccess->isFolder( uri ) )
    {
        return false;
    }

    uno::Sequence< OUString > children =
        m_xSimpleFileAccess->getFolderContents( uri, true );

    for ( sal_Int32 i = 0; i < children.getLength(); i++ )
    {
        OUString child = children[i];
        sal_Int32 idx = child.lastIndexOf(test);

        // OSL_TRACE("Trying: %s", PRTSTR(child));
        // OSL_TRACE("idx=%d, testlen=%d, children=%d",
        //     idx, test.getLength(), child.getLength());

        if ( idx != -1 && (idx + test.getLength()) == child.getLength() )
        {
            // OSL_TRACE("FOUND PATH: %s", PRTSTR(child));
            if ( bAppendScriptsPart )
            {
                m_sBaseURI = child.concat( SCRIPTS_PART );
            }
            else
            {
                m_sBaseURI = child;
            }
            return true;
        }
    }
    return false;
}

OUString
ScriptingFrameworkURIHelper::getLanguagePart(const OUString& rStorageURI)
{
    OUString result;

    sal_Int32 idx = rStorageURI.indexOf(m_sBaseURI);
    sal_Int32 len = m_sBaseURI.getLength() + 1;

    if ( idx != -1 )
    {
        result = rStorageURI.copy(idx + len);
        result = result.replace('/', '|');
    }
    return result;
}

OUString
ScriptingFrameworkURIHelper::getLanguagePath(const OUString& rLanguagePart)
{
    OUString result;
    result = rLanguagePart.replace('|', '/');
    return result;
}

OUString SAL_CALL
ScriptingFrameworkURIHelper::getScriptURI(const OUString& rStorageURI)
    throw( lang::IllegalArgumentException, uno::RuntimeException )
{
    ::rtl::OUStringBuffer buf(120);

    buf.appendAscii("vnd.sun.star.script:");
    buf.append(getLanguagePart(rStorageURI));
    buf.appendAscii("?language=");
    buf.append(m_sLanguage);
    buf.appendAscii("&location=");
    buf.append(m_sLocation);

    return buf.makeStringAndClear();
}

OUString SAL_CALL
ScriptingFrameworkURIHelper::getStorageURI(const OUString& rScriptURI)
    throw( lang::IllegalArgumentException, uno::RuntimeException )
{
    OUString sLanguagePart;
    try
    {
        uno::Reference < uri::XVndSunStarScriptUrl > xURI(
            m_xUriReferenceFactory->parse( rScriptURI ), uno::UNO_QUERY_THROW );
        sLanguagePart = xURI->getName();
    }
    catch ( uno::Exception& )
    {
        throw lang::IllegalArgumentException(
            OUString::createFromAscii( "Script URI not valid" ),
                uno::Reference< uno::XInterface >(), 1 );
    }

    ::rtl::OUStringBuffer buf(120);
    buf.append(m_sBaseURI);
    buf.append(OUString::createFromAscii("/"));
    buf.append(getLanguagePath(sLanguagePart));

    OUString result = buf.makeStringAndClear();

    return result;
}

OUString SAL_CALL
ScriptingFrameworkURIHelper::getRootStorageURI()
    throw( uno::RuntimeException )
{
    return m_sBaseURI;
}

OUString SAL_CALL
ScriptingFrameworkURIHelper::getImplementationName()
    throw( uno::RuntimeException )
{
    return OUString::createFromAscii(
        "com.sun.star.script.provider.ScriptURIHelper" );
}

sal_Bool SAL_CALL
ScriptingFrameworkURIHelper::supportsService( const OUString& serviceName )
    throw( uno::RuntimeException )
{
    OUString m_sServiceName = OUString::createFromAscii(
        "com.sun.star.script.provider.ScriptURIHelper" );

    if ( serviceName.equals( m_sServiceName ) )
    {
        return sal_True;
    }
    return sal_False;
}

uno::Sequence< ::rtl::OUString > SAL_CALL
ScriptingFrameworkURIHelper::getSupportedServiceNames()
    throw( uno::RuntimeException )
{
    ::rtl::OUString serviceNameList[] = { 
        ::rtl::OUString::createFromAscii(
            "com.sun.star.script.provider.ScriptURIHelper" ) };

    uno::Sequence< ::rtl::OUString > serviceNames = uno::Sequence <
        ::rtl::OUString > ( serviceNameList, 1 );

    return serviceNames;
}
}
