/**************************************************************
 * 
 * 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_desktop.hxx"

#include "com/sun/star/deployment/VersionException.hpp"
#include "com/sun/star/deployment/LicenseException.hpp"
#include "com/sun/star/deployment/InstallException.hpp"
#include "com/sun/star/deployment/DependencyException.hpp"
#include "com/sun/star/deployment/PlatformException.hpp"
#include "com/sun/star/task/XInteractionApprove.hpp"
#include "com/sun/star/task/XInteractionAbort.hpp"
#include "com/sun/star/task/XInteractionHandler.hpp"
#include "com/sun/star/ucb/XCommandEnvironment.hpp"
#include "com/sun/star/uno/XComponentContext.hpp"
#include "dp_commandenvironments.hxx"

namespace deployment = com::sun::star::deployment;
namespace lang  = com::sun::star::lang;
namespace task = com::sun::star::task;
namespace ucb = com::sun::star::ucb;
namespace uno = com::sun::star::uno;
namespace css = com::sun::star;

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

using ::com::sun::star::uno::Reference;
using ::rtl::OUString;

namespace dp_manager {

BaseCommandEnv::BaseCommandEnv()
{
}

BaseCommandEnv::BaseCommandEnv(
    Reference< task::XInteractionHandler> const & handler)
    : m_forwardHandler(handler)
{
}

BaseCommandEnv::~BaseCommandEnv()
{
}
// XCommandEnvironment
//______________________________________________________________________________
Reference<task::XInteractionHandler> BaseCommandEnv::getInteractionHandler()
throw (uno::RuntimeException)
{
    return this;
}

//______________________________________________________________________________
Reference<ucb::XProgressHandler> BaseCommandEnv::getProgressHandler()
throw (uno::RuntimeException)
{
    return this;
}

void BaseCommandEnv::handle(
    Reference< task::XInteractionRequest> const & /*xRequest*/ )
    throw (uno::RuntimeException)
{
}

void BaseCommandEnv::handle_(bool approve, bool abort,
                             Reference< task::XInteractionRequest> const & xRequest )
{
    if (approve == false && abort == false)
    {
        //not handled so far -> forwarding
        if (m_forwardHandler.is())
            m_forwardHandler->handle(xRequest);
        else
            return; //cannot handle
    }
    else
	{
	    // select:
        uno::Sequence< Reference< task::XInteractionContinuation > > conts(
            xRequest->getContinuations() );
        Reference< task::XInteractionContinuation > const * pConts =
            conts.getConstArray();
        sal_Int32 len = conts.getLength();
        for ( sal_Int32 pos = 0; pos < len; ++pos )
        {
            if (approve) {
                Reference< task::XInteractionApprove > xInteractionApprove(
                    pConts[ pos ], uno::UNO_QUERY );
                if (xInteractionApprove.is()) {
                    xInteractionApprove->select();
                    // don't query again for ongoing continuations:
                    approve = false;
                }
            }
            else if (abort) {
                Reference< task::XInteractionAbort > xInteractionAbort(
                    pConts[ pos ], uno::UNO_QUERY );
                if (xInteractionAbort.is()) {           
                    xInteractionAbort->select();
                    // don't query again for ongoing continuations:
                    abort = false;
                }
            }
        }
	}

}

// XProgressHandler
void BaseCommandEnv::push( uno::Any const & /*Status*/ )
throw (uno::RuntimeException)
{
}


void BaseCommandEnv::update( uno::Any const & /*Status */)
throw (uno::RuntimeException)
{
}

void BaseCommandEnv::pop() throw (uno::RuntimeException)
{
}
//==============================================================================

TmpRepositoryCommandEnv::TmpRepositoryCommandEnv()
{
}

TmpRepositoryCommandEnv::TmpRepositoryCommandEnv(
    css::uno::Reference< css::task::XInteractionHandler> const & handler):
    BaseCommandEnv(handler)
{
}
// XInteractionHandler
void TmpRepositoryCommandEnv::handle(
    Reference< task::XInteractionRequest> const & xRequest )
    throw (uno::RuntimeException)
{
    uno::Any request( xRequest->getRequest() );
    OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
    
    deployment::VersionException verExc;	
	deployment::LicenseException licExc;
    deployment::InstallException instExc;

    bool approve = false;
    bool abort = false;

    if ((request >>= verExc)
        || (request >>= licExc)
        || (request >>= instExc))
    { 
        approve = true;
    }

    handle_(approve, abort, xRequest);
}
//================================================================================

LicenseCommandEnv::LicenseCommandEnv(
    css::uno::Reference< css::task::XInteractionHandler> const & handler,
    bool bSuppressLicense,
    OUString const & repository):
    BaseCommandEnv(handler), m_repository(repository),
    m_bSuppressLicense(bSuppressLicense)
{
}
// XInteractionHandler
void LicenseCommandEnv::handle(
    Reference< task::XInteractionRequest> const & xRequest )
    throw (uno::RuntimeException)
{
    uno::Any request( xRequest->getRequest() );
    OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
    

	deployment::LicenseException licExc;

    bool approve = false;
    bool abort = false;

    if (request >>= licExc)
    {
        if (m_bSuppressLicense
            || m_repository.equals(OUSTR("bundled"))
            || licExc.AcceptBy.equals(OUSTR("admin")))
        {
            //always approve in bundled case, because we do not support
            //showing licenses anyway.
            //The "admin" already accepted the license when installing the
            // shared extension
            approve = true;
        }
    }

    handle_(approve, abort, xRequest);
}

//================================================================================
//================================================================================

NoLicenseCommandEnv::NoLicenseCommandEnv(
    css::uno::Reference< css::task::XInteractionHandler> const & handler):
    BaseCommandEnv(handler)
{
}
// XInteractionHandler
void NoLicenseCommandEnv::handle(
    Reference< task::XInteractionRequest> const & xRequest )
    throw (uno::RuntimeException)
{
    uno::Any request( xRequest->getRequest() );
    OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
    

	deployment::LicenseException licExc;

    bool approve = false;
    bool abort = false;

    if (request >>= licExc)
    {
        approve = true;
    }
    handle_(approve, abort, xRequest);
}

// SilentCheckPrerequisitesCommandEnv::SilentCheckPrerequisitesCommandEnv(
//     css::uno::Reference< css::task::XInteractionHandler> const & handler):
//     BaseCommandEnv(handler)
// {
// }
SilentCheckPrerequisitesCommandEnv::SilentCheckPrerequisitesCommandEnv()
{
}

void SilentCheckPrerequisitesCommandEnv::handle(
       Reference< task::XInteractionRequest> const & xRequest )
    throw (uno::RuntimeException)
{
    uno::Any request( xRequest->getRequest() );
    OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
    
	deployment::LicenseException licExc;
    deployment::PlatformException platformExc;
    deployment::DependencyException depExc;
    bool approve = false;
    bool abort = false;

    if (request >>= licExc)
    {
        approve = true;
        handle_(approve, abort, xRequest);
    }
    else if ((request >>= platformExc)
             || (request >>= depExc))
    {
        m_Exception = request;
    }
    else
    {
        m_UnknownException = request;
    }
}
// NoExceptionCommandEnv::NoExceptionCommandEnv(
//     css::uno::Reference< css::task::XInteractionHandler> const & handler,
//     css::uno::Type const & type):
//     BaseCommandEnv(handler),
//     m_type(type)
// {
// }
// // XInteractionHandler
// void NoExceptionCommandEnv::handle(
//     Reference< task::XInteractionRequest> const & xRequest )
//     throw (uno::RuntimeException)
// {
//     uno::Any request( xRequest->getRequest() );
//     OSL_ASSERT( request.getValueTypeClass() == uno::TypeClass_EXCEPTION );
    

// 	deployment::LicenseException licExc;

//     bool approve = false;
//     bool abort = false;

//     if (request.getValueType() == m_type)
//     {
//         approve = true;
//     }
//     handle_(approve, abort, xRequest);
// }



} // namespace dp_manager