/* libcmis
 * Version: MPL 1.1 / GPLv2+ / LGPLv2+
 *
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License or as specified alternatively below. You may obtain a copy of
 * the License at http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * Major Contributor(s):
 * Copyright (C) 2011 SUSE <cbosdonnat@suse.com>
 *
 *
 * All Rights Reserved.
 *
 * For minor contributions see the git repository.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPLv2+"), or
 * the GNU Lesser General Public License Version 2 or later (the "LGPLv2+"),
 * in which case the provisions of the GPLv2+ or the LGPLv2+ are applicable
 * instead of those above.
 */
#ifndef _LIBCMIS_TEST_DUMMIES_HXX_
#define _LIBCMIS_TEST_DUMMIES_HXX_


#include <libcmis/allowable-actions.hxx>
#include <libcmis/document.hxx>
#include <libcmis/folder.hxx>
#include <libcmis/object.hxx>
#include <libcmis/object-type.hxx>
#include <libcmis/property-type.hxx>
#include <libcmis/repository.hxx>
#include <libcmis/session.hxx>

/** This namespace contains dummy classes to simulate the libcmis layer
    in the libcmis-c unit tests.
  */
namespace dummies
{
    class Session : public libcmis::Session
    {
        public:
            Session( );
            ~Session( );

            virtual libcmis::RepositoryPtr getRepository( );
            virtual bool setRepository( std::string repositoryId );
            virtual std::vector< libcmis::RepositoryPtr > getRepositories( );
            virtual libcmis::FolderPtr getRootFolder();
            virtual libcmis::ObjectPtr getObject( std::string id );
            virtual libcmis::ObjectPtr getObjectByPath( std::string path );
            virtual libcmis::FolderPtr getFolder( std::string id );
            virtual libcmis::ObjectTypePtr getType( std::string id );
            virtual std::vector< libcmis::ObjectTypePtr > getBaseTypes( );
            virtual std::string getRefreshToken( );
            virtual void setNoSSLCertificateCheck( bool /*noCheck*/ ) { }
    };

    class Repository : public libcmis::Repository
    {
        public:
            Repository( );
            ~Repository( );
    };

    class PropertyType : public libcmis::PropertyType
    {
        public:
            PropertyType( std::string id, std::string xmlType );
            ~PropertyType( );
    };

    /** Dummy for testing the C API for allowable actions. The dummy has only the
        following actions defined:
        \li \c GetProperties, defined to \c true
        \li \c GetFolderParent, defined to \c false
      */
    class AllowableActions : public libcmis::AllowableActions
    {
        public:
            AllowableActions( );
            ~AllowableActions( );
    };

    class ObjectType : public libcmis::ObjectType
    {
        private:
            std::string m_typeId;
            std::vector< std::string > m_childrenIds;
            bool m_triggersFaults;

            ObjectType( );
            void initMembers( );

        public:
            ObjectType( bool rootType, bool triggersFaults );
            ~ObjectType( );

            virtual boost::shared_ptr< libcmis::ObjectType >  getParentType( );
            virtual boost::shared_ptr< libcmis::ObjectType >  getBaseType( );
            virtual std::vector< boost::shared_ptr< libcmis::ObjectType > > getChildren( );

            virtual std::string toString( );
    };

    class Object : public virtual libcmis::Object
    {
        public:
            std::string m_type;
            bool m_triggersFaults;

        public:
            Object( bool triggersFaults, std::string m_type = "Object" );
            ~Object( ) { }

            virtual std::string getId( );
            virtual std::string getName( );

            virtual std::vector< std::string > getPaths( );

            virtual std::string getBaseType( );
            virtual std::string getType( );

            virtual std::string getCreatedBy( ) { return m_type + "::CreatedBy"; }
            virtual boost::posix_time::ptime getCreationDate( );
            virtual std::string getLastModifiedBy( ) { return m_type + "::LastModifiedBy"; }
            virtual boost::posix_time::ptime getLastModificationDate( );

            virtual std::string getChangeToken( ) { return m_type + "::ChangeToken"; }
            virtual bool isImmutable( ) { return true; };

            virtual libcmis::ObjectPtr updateProperties(
                    const std::map< std::string, libcmis::PropertyPtr >& properties );

            virtual libcmis::ObjectTypePtr getTypeDescription( );
            virtual libcmis::AllowableActionsPtr getAllowableActions( );

            virtual void refresh( );

            virtual void remove( bool allVersions = true );
            
            virtual void move( libcmis::FolderPtr source, libcmis::FolderPtr destination );

            virtual std::string toString( ) { return m_type + "::toString"; }
            
            virtual void toXml( xmlTextWriterPtr writer );
    };

    class Folder : public libcmis::Folder, public Object
    {
        private:
            bool m_isRoot;

        public:
            Folder( bool isRoot, bool triggersFaults );
            ~Folder( ) { }
            
            virtual libcmis::FolderPtr getFolderParent( );
            virtual std::vector< libcmis::ObjectPtr > getChildren( );
            virtual std::string getPath( );

            virtual bool isRootFolder( );

            virtual libcmis::FolderPtr createFolder( const std::map< std::string, libcmis::PropertyPtr >& properties );
            virtual libcmis::DocumentPtr createDocument( const std::map< std::string, libcmis::PropertyPtr >& properties,
                                    boost::shared_ptr< std::ostream > os, std::string contentType, std::string filename );

            virtual std::vector< std::string > removeTree( bool allVersion = true,
                                    libcmis::UnfileObjects::Type unfile = libcmis::UnfileObjects::Delete,
                                    bool continueOnError = false );

            virtual std::vector< std::string > getPaths( ) { return dummies::Object::getPaths( ); }
            virtual std::string toString( ) { return dummies::Object::toString( ); }
    };

    class Document : public libcmis::Document, public Object
    {
        private:
            bool m_isFiled;
            std::string m_contentString;

        public:
            Document( bool isFiled, bool triggersFaults );
            ~Document( ) { }

            std::string getContentString( ) { return m_contentString; }

            virtual std::vector< libcmis::FolderPtr > getParents( );
            
            virtual boost::shared_ptr< std::istream > getContentStream( std::string streamId = std::string( ) );

            virtual void setContentStream( boost::shared_ptr< std::ostream > os, std::string contentType,
                                           std::string fileName, bool overwrite = true );

            virtual std::string getContentType( );
            
            virtual std::string getContentFilename( );

            virtual long getContentLength( );

            virtual libcmis::DocumentPtr checkOut( );

            virtual void cancelCheckout( );

            virtual libcmis::DocumentPtr checkIn( bool isMajor, std::string comment,
                                  const std::map< std::string, libcmis::PropertyPtr >& properties,
                                  boost::shared_ptr< std::ostream > stream,
                                  std::string contentType, std::string filename );

            virtual std::vector< libcmis::DocumentPtr > getAllVersions( );

            virtual std::vector< std::string > getPaths( ) { return dummies::Object::getPaths( ); }
            virtual std::string toString( ) { return dummies::Object::toString( ); }
    };
}

#endif
