/***************************************************************************
    This class carries custom options
                             -------------------
    begin                : Fr 29 Apr 2011
    copyright            : (C) 2011-2016 by Alexander Reinholdt
    email                : alexander.reinholdt@kdemail.net
 ***************************************************************************/

/***************************************************************************
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful, but   *
 *   WITHOUT ANY WARRANTY; without even the implied warranty of            *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU     *
 *   General Public License for more details.                              *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc., 51 Franklin Street, Suite 500, Boston,*
 *   MA 02110-1335, USA                                                    *
 ***************************************************************************/

#ifndef SMB4KCUSTOMOPTIONS_H
#define SMB4KCUSTOMOPTIONS_H

// application specific includes
#include "smb4khost.h"
#include "smb4kshare.h"
#include "smb4kglobal.h"

// Qt includes
#include <QScopedPointer>
#include <QUrl>

// KDE includes
#include <KCoreAddons/KUser>

// forward declarations
class Smb4KCustomOptionsPrivate;

using namespace Smb4KGlobal;

/**
 * This class stores the custom options defined for a certain host
 * or share.
 *
 * @author Alexander Reinholdt <alexander.reinholdt@kdemail.net>
 * @since 1.0.0
 */

class Q_DECL_EXPORT Smb4KCustomOptions
{
  friend class Smb4KCustomOptionsPrivate;
  
  public:
    /**
     * Remount enumeration
     * 
     * @param RemountOnce       Remount the share only next time the application
     *                          is started.
     * @param RemountAlways     Remount the share every time the application is
     *                          started.
     * @param RemountNever      Never remount the share.
     * @param UndefinedRemount  No remount option is defined.
     */
    enum Remount { RemountOnce,
                   RemountAlways,
                   RemountNever,
                   UndefinedRemount };
                  
#if defined(Q_OS_LINUX)
    /**
     * The SecurityMode enumeration
     */
    enum SecurityMode { NoSecurityMode,
                        Krb5,
                        Krb5i,
                        Ntlm,
                        Ntlmi,
                        Ntlmv2,
                        Ntlmv2i,
                        Ntlmssp,
                        Ntlmsspi,
                        UndefinedSecurityMode };

    /**
     * The WriteAccess enumeration
     */
    enum WriteAccess { ReadWrite,
                       ReadOnly,
                       UndefinedWriteAccess };
#endif
                       
    /**
     * The Kerberos enumeration
     */
    enum Kerberos { UseKerberos,
                    NoKerberos,
                    UndefinedKerberos };
                  
    /**
     * Constructor for a host
     */
    explicit Smb4KCustomOptions(Smb4KHost *host);
                
    /**
     * Constructor for a share
     */
    explicit Smb4KCustomOptions(Smb4KShare *share);
    
    /**
     * Copy constructor
     */
    Smb4KCustomOptions(const Smb4KCustomOptions &options);
    
    /**
     * Empty constructor
     */
    Smb4KCustomOptions();
    
    /**
     * Destructor
     */
    ~Smb4KCustomOptions();
    
    /**
     * Sets the host object. If you already set a network item before,
     * this function will do nothing.
     * 
     * @param host          The host object
     */
    void setHost(Smb4KHost *host);
    
    /**
     * Sets the share object. If you already set a host item before,
     * you can overwrite it with this function if the host names and
     * workgroup names match. This way you can propagate options that 
     * were defined for a host to one of its shares.
     * 
     * @param share         The host object
     */
    void setShare(Smb4KShare *share);
    
    /**
     * Returns the type of the network item for that the options
     * are defined
     * 
     * @returns the type of the network item
     */
    Smb4KGlobal::NetworkItem type() const;
    
    /**
     * If the network item is of type Share, set if it should be remounted.
     * If the network item is not of type Share, this function does nothing.
     * 
     * @param remount       One entry of the Remount enumeration
     */
    void setRemount(Remount remount);
    
    /**
     * Returns if the network item should be remounted.
     * 
     * @returns if the network item should be remounted.
     */
    Remount remount() const;
    
    /**
     * Set the profile this custom options object belongs to. The profile is 
     * meant to distinguish between several network environments, like home
     * and work.
     * 
     * @param profile         The profile name
     */
    void setProfile(const QString &profile);
    
    /**
     * Returns the name of the profile this custom options object belongs to.
     * 
     * @returns the profile name
     */
    QString profile() const;
    
    /**
     * Sets the workgroup name.
     * 
     * @param workgroup       The workgroup name
     */
    void setWorkgroupName(const QString &workgroup);
    
    /**
     * Returns the workgroup name.
     * 
     * @returns the workgroup name.
     */
    QString workgroupName() const;

    /**
     * Sets the UNC/URL of the network item
     * 
     * @param url             The URL
     */
    void setURL(const QUrl &url);
    
    /**
     * Sets the UNC/URL of the network item
     *
     * @param url             The URL of the network item
     */
    void setURL(const QString &url);
    
    /**
     * Returns the URL of the network item
     * 
     * @returns the URL
     */
    QUrl url() const;

    /**
     * Returns the UNC in the form //HOST/Share.
     * 
     * This function should only be used for basic comparisons or for display
     * purposes. If you need to do sophisticated comparisons, use the url() 
     * function instead.
     *
     * @returns the UNC.
     */
    QString unc() const;

    /**
     * Returns the host name.
     *
     * @returns the host name.
     */
    QString hostName() const;

    /**
     * Returns the share name, if appropriate, or an empty string.
     *
     * @returns the share name
     */
    QString shareName() const;
                                                   
    /**
     * Sets the IP address for the network item
     * 
     * @param ip              The IP address
     */
    void setIP(const QString &ip);
    
    /**
     * Returns the IP address of the network item
     * 
     * @returns the IP address
     */
    QString ip() const;
    
    /**
     * Set the SMB port to use with this host or share.
     * 
     * @param port            The SMB port
     */
    void setSMBPort(int port);
    
    /**
     * Returns the SMB port. The default value is 139.
     * 
     * @returns the SMB port
     */
    int smbPort() const;
    
#if defined(Q_OS_LINUX)
    /**
     * Set the port that is to be used with mounting for a single share or all
     * shares of a host.
     * 
     * @param port            The file system port
     */
    void setFileSystemPort(int port);
    
    /**
     * Returns the file system port. The default value is 445.
     * 
     * @returns the file system port
     */
    int fileSystemPort() const;
    
    /**
     * Set the security mode for mounting.
     *
     * @param mode            The security mode
     */
    void setSecurityMode(SecurityMode mode);

    /**
     * Returns the security mode for mounting a specific share.
     *
     * @returns the security mode
     */
    SecurityMode securityMode() const;

    /**
     * Set the write access for either a single share or all shares of a host. 
     * 
     * @param access          The write access
     */
    void setWriteAccess(WriteAccess access);
    
    /**
     * Returns the write access for the share.
     * 
     * @returns the write access
     */
    WriteAccess writeAccess() const;
#endif

    /**
     * Sets the useage of Kerberos for this network item.
     * 
     * @param kerberos          Kerberos usage
     */
    void setUseKerberos(Kerberos kerberos);
    
    /**
     * Returns the usage of Kerberos for this network item.
     * 
     * @returns the usage of Kerberos
     */
    Kerberos useKerberos() const;
    
    /**
     * Set the user who owns the share.
     * @param user    The user
     */
    void setUser(const KUser &user);
    
    /**
     * Returns the user who owns the share.
     * @returns the user
     */
    KUser user() const;
    
    /**
     * Set the group that owns the share.
     * @param group   The group
     */
    void setGroup(const KUserGroup &group);
    
    /**
     * Returns the group that owns the share.
     * @returns the group
     */
    KUserGroup group() const;
    
    /**
     * This function sets the MAC address of a host. In case the options 
     * represent a share this is the MAC address of the host that shares 
     * the resource.
     * 
     * @param macAddress        The MAC address of the host
     */
    void setMACAddress(const QString &macAddress);
    
    /**
     * This function returns the MAC address of the host or an empty string if 
     * no MAC address was defined.
     *
     * @returns the MAC address of the host.
     */
    QString macAddress() const;
    
    /**
     * Set whether a magic WOL package should be send to the host that this 
     * network item represents or where this network item is located before scanning 
     * the entire network.
     * 
     * @param send              Boolean that determines if a magic WOL package
     *                          is to be sent.
     */
    void setWOLSendBeforeNetworkScan(bool send);
    
    /**
     * Send a magic WOL package to the host that this network item represents
     * or where this network item is located before scanning the entire network.
     * 
     * @returns TRUE if a magic WOL package should be send on first network
     * scan.
     */
    bool wolSendBeforeNetworkScan() const;
    
    /**
     * Set whether a magic WOL package should be send to the host that this 
     * network item represents or where this network item is located before a 
     * mount attempt.
     * 
     * @param send              Boolean that determines if a magic WOL package
     *                          is to be sent.
     */
    void setWOLSendBeforeMount(bool send);
    
    /**
     * Send a magic WOL package to the host that this network item represents
     * or where this network item is located before a mount attempt.
     * 
     * @returns TRUE if a magic WOL package should be send on first network
     * scan.
     */
    bool wolSendBeforeMount() const;
    
    /**
     * This function returns all custom options in a sorted map. The UNC,
     * workgroup and IP address must be retrieved separately if needed.
     *
     * Note that all entries that are set and valid are returned here. This
     * also comprises default values (e.g. the default SMB port). If you need 
     * to check if a certain value is a custom option or not, you need to implement 
     * this check.
     *
     * @returns all valid entries.
     */
    QMap<QString,QString> customOptions() const;
    
    /**
     * Check if the custom options @p options are equal to those defined here. If
     * you just want to check if the options have the same UNC and workgroup and 
     * belong to the same profile, set @p fullCheck to FALSE.
     * 
     * @param options             The options that are to be compared to the
     *                            ones defined here
     * @param fullCheck           Set this to FALSE if you just want to check
     *                            the profile, UNC and workgroup.
     */
    bool equals(Smb4KCustomOptions *options, bool fullCheck = true) const;
    
    /**
     * Operator to check if two custom options objects are equal.
     */
    bool operator==(Smb4KCustomOptions options) const { return equals(&options, true); }
    
    /**
     * Check if the custom options are empty.
     * 
     * @returns TRUE if the custom options object is empty
     */
    bool isEmpty();
    
  private:
    const QScopedPointer<Smb4KCustomOptionsPrivate> d;
};

#endif

