#ifndef KEYZY_LICENSE_ACTIVATOR_H
#define KEYZY_LICENSE_ACTIVATOR_H

/**
 * @file KeyzyLicenseActivator.h
 * @brief License activation and deactivation (online, semi-online, and offline flows).
 */

#include "KeyzyLicenseManager.h"
#include "KeyzyLicenseValidator.h"
#include "LicenseDepositHandler.h"

namespace Keyzy
{
    class KeyzyLicenseProvider;
    
    /*!
     * @brief Activates and deactivates licenses — online, semi-online, offline, trial, and upgrade flows. The main entry point for most integrations.
     */
    class KeyzyLicenseActivator
    {
        // Constructors - Destructors
    public:
        /*!
         * Create an instance of KeyzyLicenseActivator that will activate / deactivate licenses for a product defined in ProductData structure
         * @param productData Structure that describes a product for which going to set/delete licenses
         */
        KeyzyLicenseActivator(const ProductData& productData);
        ~KeyzyLicenseActivator();
        
        // Activations - Deactivations
    public:
        /*!
         * Sets the serial number to the device and validate it with KEYZY service
         * If the validation fails, it deletes the serial number from the device
         */
        LicenseStatus activateOnline(const std::string& serialNumber);
        
        /*!
         * Deactivate the license with KEYZY service and delete the serial number from the device
         */
        LicenseStatus deactivateOnline();
        
        /*!
         * Downloads the license file from KEYZY service with given serial number,
         * validate the license file and keep the license file and serial number in the device.
         * If there is a license file or serial number in the device before, they will be overwriten.
         * If the validation fails, it deletes the license file and the serial number from the device.
         * @param std::string serialNumber the license serial number
         */
        LicenseStatus activateSemiOnline(const std::string& serialNumber);
        
        /*!
         * Downloads the license file from KEYZY service with the serial number which was kept before,
         * validate the license file and keep it in the device
         * If the validation fails, it deletes the license file and the serial number from the device.
         * @param std::string serialNumber the license serial number
         */
        LicenseStatus activateSemiOnline();
        
        /*!
         * Checks if the device can reach KEYZY service. Delete the license file.
         * Deactivate the license with KEYZY service.
         */
        LicenseStatus deactivateSemiOnline();
        
        /*!
         * This is not a real activation, it doesn't connected to KEYZY service.
         * Your user should download the license file on the internet first and
         * that is the activation for KEYZY service.
         * We strongly recommend to set Offline License Life for offline licenses
         * in KEYZY app even they are perpetual licenses.
         */
        LicenseStatus activateOffline(const std::string& licenseFilePath);
        
        /*!
         * This is not a real deactivation, it doesn't connected to KEYZY service.
         * Deletes the license file form the device only.
         */
        bool deactivateOffline();
        
        /*!
         * Creates a local (client-only) trial license stored on the device.
         * The expiration is checked locally against the system clock.
         *
         * For server-side trial licenses, obtain a trial serial either via
         * LicenseDepositHandler::registerTrial() or from your own distribution channel
         * (e.g. your website), then activate it using any of the standard methods:
         * activateOnline(), activateSemiOnline() or activateOffline().
         * The same applies for validation and deactivation — server-side trials
         * follow the same flow as perpetual and subscription licenses.
         *
         * @param endTime Due date of trial license
         * @return LicenseStatus::VALID, LicenseStatus::EXPIRED, LicenseStatus::INVALID
         */
        LicenseStatus activateClientTrial(const std::tm& endTime);

        /*!
         * Deletes local (client-only) trial license from the device.
         * Does not affect server-side trial licenses.
         * @return true if it's success, false if it's failed.
         */
        bool deactivateClientTrial();
        
        // Upgrade
    public:
        /*!
         * Upgrade a license using the stored serial as the source.
         * Reads the currently stored serial number from the device.
         *
         * @note This method only performs the upgrade on the KEYZY server.
         * It does not activate or validate the new license, and does not
         * store the target serial on the device. To activate the target
         * serial afterward, use one of the activation methods
         * (e.g. activateOnline, activateSemiOnline).
         *
         * @param targetSerial Target serial number to upgrade to
         * @return LicenseStatus::VALID on success,
         *         LicenseStatus::CLIENT_SERIAL_DOES_NOT_EXIST if no source serial is stored
         */
        LicenseStatus upgradeLicense(const std::string& targetSerial);

        /*!
         * Upgrade a license by providing both source and target serials explicitly.
         *
         * @note This method only performs the upgrade on the KEYZY server.
         * It does not activate or validate the new license, and does not
         * store the target serial on the device. To activate the target
         * serial afterward, use one of the activation methods
         * (e.g. activateOnline, activateSemiOnline).
         *
         * @param sourceSerial Source serial number (current license)
         * @param targetSerial Target serial number to upgrade to
         * @return LicenseStatus
         */
        LicenseStatus upgradeLicense(const std::string& sourceSerial,
                                     const std::string& targetSerial);
        
        std::shared_ptr<KeyzyLicenseValidator> getLicenseValidator();
        std::shared_ptr<LicenseDepositHandler> getLicenseDepositHandler();
        
    private:
        std::shared_ptr<KeyzyLicenseProvider> _licenseProvider;
        std::unique_ptr<KeyzyLicenseManager> _licenseManager;
        std::shared_ptr<KeyzyLicenseValidator> _licenseValidator;
        std::shared_ptr<LicenseDepositHandler> _licenseDepositHandler;
    };
} // Keyzy

#endif // KEYZY_LICENSE_ACTIVATOR_H
