// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { ipRangeToString } from "./SasIPRange.js";
import { truncatedISO8061Date } from "../utils/utils.common.js";
/**
 * Protocols for generated SAS.
 */
export var SASProtocol;
(function (SASProtocol) {
    /**
     * Protocol that allows HTTPS only
     */
    SASProtocol["Https"] = "https";
    /**
     * Protocol that allows both HTTPS and HTTP
     */
    SASProtocol["HttpsAndHttp"] = "https,http";
})(SASProtocol || (SASProtocol = {}));
/**
 * Represents the components that make up an Azure Storage SAS' query parameters. This type is not constructed directly
 * by the user; it is only generated by the {@link AccountSASSignatureValues} and {@link BlobSASSignatureValues}
 * types. Once generated, it can be encoded into a {@link String} and appended to a URL directly (though caution should
 * be taken here in case there are existing query parameters, which might affect the appropriate means of appending
 * these query parameters).
 *
 * NOTE: Instances of this class are immutable.
 */
export class SASQueryParameters {
    /**
     * The storage API version.
     */
    version;
    /**
     * Optional. The allowed HTTP protocol(s).
     */
    protocol;
    /**
     * Optional. The start time for this SAS token.
     */
    startsOn;
    /**
     * Optional only when identifier is provided. The expiry time for this SAS token.
     */
    expiresOn;
    /**
     * Optional only when identifier is provided.
     * Please refer to {@link AccountSASPermissions}, {@link BlobSASPermissions}, or {@link ContainerSASPermissions} for
     * more details.
     */
    permissions;
    /**
     * Optional. The storage services being accessed (only for Account SAS). Please refer to {@link AccountSASServices}
     * for more details.
     */
    services;
    /**
     * Optional. The storage resource types being accessed (only for Account SAS). Please refer to
     * {@link AccountSASResourceTypes} for more details.
     */
    resourceTypes;
    /**
     * Optional. The signed identifier (only for {@link BlobSASSignatureValues}).
     *
     * @see https://learn.microsoft.com/rest/api/storageservices/establishing-a-stored-access-policy
     */
    identifier;
    /**
     * Optional. Beginning in version 2025-07-05, this value specifies the Entra ID of the user would is authorized to
     * use the resulting SAS URL.  The resulting SAS URL must be used in conjunction with an Entra ID token that has been
     * issued to the user specified in this value.
     */
    delegatedUserObjectId;
    /**
     * Optional. Encryption scope to use when sending requests authorized with this SAS URI.
     */
    encryptionScope;
    /**
     * Optional. Specifies which resources are accessible via the SAS (only for {@link BlobSASSignatureValues}).
     * @see https://learn.microsoft.com/rest/api/storageservices/create-service-sas#specifying-the-signed-resource-blob-service-only
     */
    resource;
    /**
     * The signature for the SAS token.
     */
    signature;
    /**
     * Value for cache-control header in Blob/File Service SAS.
     */
    cacheControl;
    /**
     * Value for content-disposition header in Blob/File Service SAS.
     */
    contentDisposition;
    /**
     * Value for content-encoding header in Blob/File Service SAS.
     */
    contentEncoding;
    /**
     * Value for content-length header in Blob/File Service SAS.
     */
    contentLanguage;
    /**
     * Value for content-type header in Blob/File Service SAS.
     */
    contentType;
    /**
     * Inner value of getter ipRange.
     */
    ipRangeInner;
    /**
     * The Azure Active Directory object ID in GUID format.
     * Property of user delegation key.
     */
    signedOid;
    /**
     * The Azure Active Directory tenant ID in GUID format.
     * Property of user delegation key.
     */
    signedTenantId;
    /**
     * The date-time the key is active.
     * Property of user delegation key.
     */
    signedStartsOn;
    /**
     * The date-time the key expires.
     * Property of user delegation key.
     */
    signedExpiresOn;
    /**
     * Abbreviation of the Azure Storage service that accepts the user delegation key.
     * Property of user delegation key.
     */
    signedService;
    /**
     * The service version that created the user delegation key.
     * Property of user delegation key.
     */
    signedVersion;
    /**
     * Authorized AAD Object ID in GUID format. The AAD Object ID of a user authorized by the owner of the User Delegation Key
     * to perform the action granted by the SAS. The Azure Storage service will ensure that the owner of the user delegation key
     * has the required permissions before granting access but no additional permission check for the user specified in
     * this value will be performed. This is only used for User Delegation SAS.
     */
    preauthorizedAgentObjectId;
    /**
     * A GUID value that will be logged in the storage diagnostic logs and can be used to correlate SAS generation with storage resource access.
     * This is only used for User Delegation SAS.
     */
    correlationId;
    /**
     * Optional. IP range allowed for this SAS.
     *
     * @readonly
     */
    get ipRange() {
        if (this.ipRangeInner) {
            return {
                end: this.ipRangeInner.end,
                start: this.ipRangeInner.start,
            };
        }
        return undefined;
    }
    constructor(version, signature, permissionsOrOptions, services, resourceTypes, protocol, startsOn, expiresOn, ipRange, identifier, resource, cacheControl, contentDisposition, contentEncoding, contentLanguage, contentType, userDelegationKey, preauthorizedAgentObjectId, correlationId, encryptionScope, delegatedUserObjectId) {
        this.version = version;
        this.signature = signature;
        if (permissionsOrOptions !== undefined && typeof permissionsOrOptions !== "string") {
            // SASQueryParametersOptions
            this.permissions = permissionsOrOptions.permissions;
            this.services = permissionsOrOptions.services;
            this.resourceTypes = permissionsOrOptions.resourceTypes;
            this.protocol = permissionsOrOptions.protocol;
            this.startsOn = permissionsOrOptions.startsOn;
            this.expiresOn = permissionsOrOptions.expiresOn;
            this.ipRangeInner = permissionsOrOptions.ipRange;
            this.identifier = permissionsOrOptions.identifier;
            this.delegatedUserObjectId = permissionsOrOptions.delegatedUserObjectId;
            this.encryptionScope = permissionsOrOptions.encryptionScope;
            this.resource = permissionsOrOptions.resource;
            this.cacheControl = permissionsOrOptions.cacheControl;
            this.contentDisposition = permissionsOrOptions.contentDisposition;
            this.contentEncoding = permissionsOrOptions.contentEncoding;
            this.contentLanguage = permissionsOrOptions.contentLanguage;
            this.contentType = permissionsOrOptions.contentType;
            if (permissionsOrOptions.userDelegationKey) {
                this.signedOid = permissionsOrOptions.userDelegationKey.signedObjectId;
                this.signedTenantId = permissionsOrOptions.userDelegationKey.signedTenantId;
                this.signedStartsOn = permissionsOrOptions.userDelegationKey.signedStartsOn;
                this.signedExpiresOn = permissionsOrOptions.userDelegationKey.signedExpiresOn;
                this.signedService = permissionsOrOptions.userDelegationKey.signedService;
                this.signedVersion = permissionsOrOptions.userDelegationKey.signedVersion;
                this.preauthorizedAgentObjectId = permissionsOrOptions.preauthorizedAgentObjectId;
                this.correlationId = permissionsOrOptions.correlationId;
            }
        }
        else {
            this.services = services;
            this.resourceTypes = resourceTypes;
            this.expiresOn = expiresOn;
            this.permissions = permissionsOrOptions;
            this.protocol = protocol;
            this.startsOn = startsOn;
            this.ipRangeInner = ipRange;
            this.delegatedUserObjectId = delegatedUserObjectId;
            this.encryptionScope = encryptionScope;
            this.identifier = identifier;
            this.resource = resource;
            this.cacheControl = cacheControl;
            this.contentDisposition = contentDisposition;
            this.contentEncoding = contentEncoding;
            this.contentLanguage = contentLanguage;
            this.contentType = contentType;
            if (userDelegationKey) {
                this.signedOid = userDelegationKey.signedObjectId;
                this.signedTenantId = userDelegationKey.signedTenantId;
                this.signedStartsOn = userDelegationKey.signedStartsOn;
                this.signedExpiresOn = userDelegationKey.signedExpiresOn;
                this.signedService = userDelegationKey.signedService;
                this.signedVersion = userDelegationKey.signedVersion;
                this.preauthorizedAgentObjectId = preauthorizedAgentObjectId;
                this.correlationId = correlationId;
            }
        }
    }
    /**
     * Encodes all SAS query parameters into a string that can be appended to a URL.
     *
     */
    toString() {
        const params = [
            "sv",
            "ss",
            "srt",
            "spr",
            "st",
            "se",
            "sip",
            "si",
            "ses",
            "skoid", // Signed object ID
            "sktid", // Signed tenant ID
            "skt", // Signed key start time
            "ske", // Signed key expiry time
            "sks", // Signed key service
            "skv", // Signed key version
            "sr",
            "sp",
            "sig",
            "rscc",
            "rscd",
            "rsce",
            "rscl",
            "rsct",
            "saoid",
            "scid",
            "sduoid", // Signed key user delegation object ID
        ];
        const queries = [];
        for (const param of params) {
            switch (param) {
                case "sv":
                    this.tryAppendQueryParameter(queries, param, this.version);
                    break;
                case "ss":
                    this.tryAppendQueryParameter(queries, param, this.services);
                    break;
                case "srt":
                    this.tryAppendQueryParameter(queries, param, this.resourceTypes);
                    break;
                case "spr":
                    this.tryAppendQueryParameter(queries, param, this.protocol);
                    break;
                case "st":
                    this.tryAppendQueryParameter(queries, param, this.startsOn ? truncatedISO8061Date(this.startsOn, false) : undefined);
                    break;
                case "se":
                    this.tryAppendQueryParameter(queries, param, this.expiresOn ? truncatedISO8061Date(this.expiresOn, false) : undefined);
                    break;
                case "sip":
                    this.tryAppendQueryParameter(queries, param, this.ipRange ? ipRangeToString(this.ipRange) : undefined);
                    break;
                case "si":
                    this.tryAppendQueryParameter(queries, param, this.identifier);
                    break;
                case "ses":
                    this.tryAppendQueryParameter(queries, param, this.encryptionScope);
                    break;
                case "skoid": // Signed object ID
                    this.tryAppendQueryParameter(queries, param, this.signedOid);
                    break;
                case "sktid": // Signed tenant ID
                    this.tryAppendQueryParameter(queries, param, this.signedTenantId);
                    break;
                case "skt": // Signed key start time
                    this.tryAppendQueryParameter(queries, param, this.signedStartsOn ? truncatedISO8061Date(this.signedStartsOn, false) : undefined);
                    break;
                case "ske": // Signed key expiry time
                    this.tryAppendQueryParameter(queries, param, this.signedExpiresOn ? truncatedISO8061Date(this.signedExpiresOn, false) : undefined);
                    break;
                case "sks": // Signed key service
                    this.tryAppendQueryParameter(queries, param, this.signedService);
                    break;
                case "skv": // Signed key version
                    this.tryAppendQueryParameter(queries, param, this.signedVersion);
                    break;
                case "sr":
                    this.tryAppendQueryParameter(queries, param, this.resource);
                    break;
                case "sp":
                    this.tryAppendQueryParameter(queries, param, this.permissions);
                    break;
                case "sig":
                    this.tryAppendQueryParameter(queries, param, this.signature);
                    break;
                case "rscc":
                    this.tryAppendQueryParameter(queries, param, this.cacheControl);
                    break;
                case "rscd":
                    this.tryAppendQueryParameter(queries, param, this.contentDisposition);
                    break;
                case "rsce":
                    this.tryAppendQueryParameter(queries, param, this.contentEncoding);
                    break;
                case "rscl":
                    this.tryAppendQueryParameter(queries, param, this.contentLanguage);
                    break;
                case "rsct":
                    this.tryAppendQueryParameter(queries, param, this.contentType);
                    break;
                case "saoid":
                    this.tryAppendQueryParameter(queries, param, this.preauthorizedAgentObjectId);
                    break;
                case "scid":
                    this.tryAppendQueryParameter(queries, param, this.correlationId);
                    break;
                case "sduoid":
                    this.tryAppendQueryParameter(queries, param, this.delegatedUserObjectId);
                    break;
            }
        }
        return queries.join("&");
    }
    /**
     * A private helper method used to filter and append query key/value pairs into an array.
     *
     * @param queries -
     * @param key -
     * @param value -
     */
    tryAppendQueryParameter(queries, key, value) {
        if (!value) {
            return;
        }
        key = encodeURIComponent(key);
        value = encodeURIComponent(value);
        if (key.length > 0 && value.length > 0) {
            queries.push(`${key}=${value}`);
        }
    }
}
//# sourceMappingURL=SASQueryParameters.js.map