#ifndef KEYZY_TYPES_H
#define KEYZY_TYPES_H

/**
 * @file KeyzyTypes.h
 * @brief Public types for the Keyzy client SDK: LicenseStatus, LicenseType, ProductData, License.
 */

#include <string>
#include <ctime>

namespace Keyzy
{
    /** @struct ProductData
     *  @brief Your product's identity and credentials — construct one and pass it to KeyzyLicenseActivator to authenticate with the KEYZY service.
     *
     *  @var ProductData::_appId
     *  Member 'appId' contains Id for authentication to Keyzy
     *  @var ProductData::_apiKey
     *  Member 'apiKey' contains Key for authentication to Keyzy

     *  @var ProductData::_productCode
     *  Member '_productCode' contains product identifier that is defined on Keyzy Dashboard

     *  @var ProductData::_cryptionKey
     *  Member '_cryptionKey' contains cryption key uses for offline license verificaiton

     *  @var ProductData::_useHostIdInOffilneActivation
     *  Member '_useHostIdInOffilneActivation' if set true, the host_id will be used to mix with _cryptionKey, so as a result a license file will be device specific
    */
    struct ProductData
    {
        ProductData() : _useHostIdInOffilneActivation(true) {}
        
        ProductData(std::string appId, std::string apiKey, std::string productCode,
                    std::string cryptionKey, bool useHostIdInOfflineActivation = true)
        : _appId(appId)
        , _apiKey(apiKey)
        , _productCode(productCode)
        , _cryptionKey(cryptionKey)
        , _useHostIdInOffilneActivation(useHostIdInOfflineActivation) {}

        std::string _appId;
        std::string _apiKey;
        std::string _productCode;
        std::string _cryptionKey;
        bool _useHostIdInOffilneActivation;
    };

    /** @struct LicenseInfo
     *  @brief License details filled in by the SDK: SKU, product code, licensee name/email, type, dates, info text, and serial number.
     *
     *  Contains license information
     *
     *  @var LicenseInfo::_skuNumber
     *  Contains the unique SKU number of the sku
     *
     *  @var LicenseInfo::_productCode
     *  Contains the unique product code of the product
     *
     *  @var LicenseInfo::_licenseeName
     *  Contains the name of the licensee
     *
     *  @var LicenseInfo::_licenseeEmail
     *  Contains the email of the licensee
     *
     *  @var LicenseInfo::_versionCode
     *  Contains the version code of the product that is connected to the SKU
     *
     *  @var LicenseInfo::_licenseType
     *  Contains the type of the license. It's "trial"
     *
     *  @var LicenseInfo::_startTime
     *  Contains the start time of the trial license in unix timestamp format.\n
     *  Default time is 315522000.\n
     *  It's only used for trial and subscription license types.\n
     *
     *  @var LicenseInfo::_endTime
     *  Contains the end time of the trial license in unix timestamp format.\n
     *  Default time is 315522000.\n
     *  It's used for trial and subscription license types as end time.\n
     *  It's used for perpetual license type as offline_license_life.
     *
     *  @var LicenseInfo::_info
     *  Contains the text for the license if any text is applied before the deposit process
     *
     *  @var LicenseInfo::_serialNumber
     *  Contains the serial number of the license
     *
    */
    struct LicenseInfo
    {
        std::string _skuNumber;
        std::string _productCode;
        std::string _licenseeName;
        std::string _licenseeEmail;
        std::string _versionCode;
        std::string _licenseType;
        std::int64_t _startTime = 315522000;
        std::int64_t _endTime = 315522000;
        std::string _info;
        std::string _serialNumber;
    };

    /*!
    * List of available status for licenses
    * VALID and ACTIVATION_DELETED are Successful. Others are Error.
    */
    enum class LicenseStatus
    {
        VALID,             ///< The license is valid and active. The only success status for validation/activation calls (with ACTIVATION_DELETED for the deactivation flow).
        EXPIRED,           ///< A locally-stored trial has expired. Returned by validateTrialLicense() in KeyzyLicenseValidator. *(Client-side)*
        INVALID,           ///< The license is invalid or could not be verified — generic failure when no more specific status applies.
        NOT_AUTHORIZED,             ///< The appId / apiKey pair is wrong or not authorized. *(Server-side)*
        SERIAL_INVALID,             ///< The serial number is invalid or not registered. *(Server-side)*
        PRODUCT_NOT_EXIST,          ///< The product code does not exist. *(Server-side)*
        PRODUCT_NOT_EXIST_FOR_USER, ///< The product code does not exist. *(Server-side)* (Intentionally identical to PRODUCT_NOT_EXIST — see note below; the distinct enum value is for internal use only.)
        PRODUCT_NOT_ACTIVE,         ///< The product exists but is not active. *(Server-side)*
        SKU_NOT_EXIST,              ///< The SKU does not exist. *(Server-side)*
        SKU_NOT_ACTIVE,             ///< The SKU exists but is not active. *(Server-side)*
        REACHED_MAX_NUMBER_OF_HOST, ///< The license has reached its maximum number of activated devices (hosts). *(Server-side)*
        PRODUCT_NOT_EXIST_FOR_SKU,  ///< The product exists but is not part of the SKU linked to this license. *(Server-side)*
        ACTIVATION_DEACTIVATED,           ///< This device's activation was deactivated (revoked) on the server. *(Server-side)*
        SUBSCRIPTION_LICENSE_EXPIRED,     ///< The subscription license has expired (its end date has passed). *(Server-side)*
        SUBSCRIPTION_LICENSE_NOT_STARTED, ///< The subscription license has not started yet (it has a future start date). *(Server-side)*
        TRIAL_LICENSE_EXPIRED,            ///< The server-side trial license has expired. (Distinct from EXPIRED, which is a *local* trial check.) *(Server-side)*
        TRIAL_LICENSE_NOT_STARTED,        ///< The server-side trial license has not started yet (future start date). *(Server-side)*
        CANNOT_KEEP_SERIAL,           ///< The SDK could not save the serial number to the device (write failed). Happens locally, before any server contact. *(Client-side)*
        CANNOT_KEEP_LICENSE_FILE,     ///< The SDK could not save the license file to the device (write failed — often a wrong or unwritable target path). Happens locally. *(Client-side)*
        ACTIVATION_DELETED, ///< The activation was successfully removed from the KEYZY servers. A success status, returned by the deactivation flow. *(Server-side)*
        CLIENT_SERIAL_DOES_NOT_EXIST, ///< No serial number is stored on the device. *(Client-side)*
        CONNECTION_ERROR,             ///< Network or firewall error (umbrella). Returned when the connection fails at the network layer and no more specific NETWORK_* status applies. *(Client-side)*
        TOO_MANY_REQUESTS,          ///< The client sent too many requests in a short time and was rate-limited (HTTP 429). *(Server-side)*
        NO_ACTIVE_SUBSCRIPTION,     ///< The account holder has a subscription problem on the KEYZY side (i.e. *your own* KEYZY plan is inactive — not the end user's license). *(Server-side)*
        CURRENT_LICENSE_DOES_NOT_EXIST, ///< During an upgrade, the source (current) license serial does not exist on the KEYZY servers. *(Server-side)*
        UPGRADE_LICENSE_DOES_NOT_EXIST, ///< During an upgrade, the target (upgrade) license serial does not exist on the KEYZY servers. *(Server-side)*
        UPGRADE_LICENSE_DOES_NOT_MATCH, ///< The target license is not a valid upgrade path for the current license. *(Server-side)*
        ANOTHER_TRIAL_LICENSE_ALREADY_ACTIVATED, ///< A trial has already been activated on this device; a second trial is blocked. *(Server-side)*
        SKU_NUMBER_VALIDATION,   ///< The sku_number parameter failed validation (HTTP 422). *(Server-side)*
        PRODUCT_CODE_VALIDATION, ///< The product_code parameter failed validation (HTTP 422). *(Server-side)*
        NAME_VALIDATION,         ///< The name parameter failed validation (HTTP 422). *(Server-side)*
        EMAIL_VALIDATION,        ///< The email parameter failed validation. Rejected server-side (HTTP 422) or client-side (empty email in register* calls). *(Server-side & Client-side)*
        NO_FREE_LICENSES,           ///< No unassigned (free) licenses remain in this SKU's pool to register. Returned by registration flows (including trial registration) when the pool is exhausted — generate more licenses for the SKU. *(Server-side)*
        NAME_OR_EMAIL_VALIDATION,   ///< @deprecated Since the 2026-04-20 server hardening, never produced by the current server. Kept for ABI compatibility — do not rely on it.
        LICENSE_NOT_EXIST_NOT_ASSIGNED_DEALER_ALREADY_DEPOSITED, ///< Register-offline-distributed-license flow: the license does not exist, is not assigned to a dealer, or has already been deposited. *(Server-side)*
        SERIAL_VALIDATION,       ///< The serial parameter failed validation (HTTP 422 on register). *(Server-side)*
        CODE_VALIDATION,         ///< The code parameter failed validation (HTTP 422 on register-trial). *(Server-side)*

        // Network diagnostic statuses (SDK 1.9.0+). All are client-detected and
        // returned by any method that makes a network request, when the call fails
        // at the network layer (see the README error table for the full method list).
        NETWORK_DNS_FAILED,        ///< DNS resolution failed (DoH and OS resolver both failed). Likely no internet, or DNS blocked. Ask the user to check their internet connection.
        NETWORK_REFUSED,           ///< TCP connection refused — typically a firewall blocking outbound HTTPS. Ask the user to check their firewall settings.
        NETWORK_TIMEOUT,           ///< Connection timed out. With no HTTP 407, this is usually a firewall blocking outbound HTTPS or a proxy silently dropping the connection. Ask the user to check firewall/proxy settings.
        NETWORK_TLS_FAILED,        ///< TLS handshake failed — corporate SSL inspection, MITM, or a wrong system clock. Ask the user to check the system date/time and any security software.
        NETWORK_PROXY_REQUIRED,    ///< HTTP 407: the network requires an authenticated proxy. Ask the user to contact their IT department to whitelist api.keyzy.io, or to configure proxy credentials at the OS level.
        NETWORK_HOSTS_TAMPERED     ///< The OS resolver returned a private/loopback IP for api.keyzy.io — a strong sign of hosts-file / DNS manipulation. Advise the user to check their hosts file.
    };

    /*!
    * List of available types for licenses
    */
    enum class LicenseType
    {
        NOTYPE,
        PERPETUAL,
        TRIAL,
        SUBSCRIPTION
    };

}; // Keyzy

#endif // KEYZY_TYPES_H
