// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { StorageSharedKeyCredential } from "@azure/storage-common";
import { FileSASPermissions } from "./FileSASPermissions.js";
import { ipRangeToString } from "./SasIPRange.js";
import { SASQueryParameters } from "./SASQueryParameters.js";
import { ShareSASPermissions } from "./ShareSASPermissions.js";
import { SERVICE_VERSION } from "./utils/constants.js";
import { truncatedISO8061Date } from "./utils/utils.common.js";
import { UserDelegationKeyCredential } from "@azure/storage-common";
/**
 * ONLY AVAILABLE IN NODE.JS RUNTIME.
 *
 * Creates an instance of SASQueryParameters.
 *
 * Only accepts required settings needed to create a SAS. For optional settings please
 * set corresponding properties directly, such as permissions, startsOn and identifier.
 *
 * WARNING: When identifier is not provided, permissions and expiresOn are required.
 * You MUST assign value to identifier or expiresOn & permissions manually if you initial with
 * this constructor.
 *
 * @param fileSASSignatureValues -
 * @param sharedKeyCredential -
 */
export function generateFileSASQueryParameters(fileSASSignatureValues, sharedKeyCredentialOrUserDelegationKey, accountName) {
    return generateFileSASQueryParametersInternal(fileSASSignatureValues, sharedKeyCredentialOrUserDelegationKey, accountName).sasQueryParameters;
}
export function generateFileSASQueryParametersInternal(fileSASSignatureValues, sharedKeyCredentialOrUserDelegationKey, accountName) {
    const version = fileSASSignatureValues.version ? fileSASSignatureValues.version : SERVICE_VERSION;
    const sharedKeyCredential = sharedKeyCredentialOrUserDelegationKey instanceof StorageSharedKeyCredential
        ? sharedKeyCredentialOrUserDelegationKey
        : undefined;
    let userDelegationKeyCredential;
    if (sharedKeyCredential === undefined && accountName !== undefined) {
        userDelegationKeyCredential = new UserDelegationKeyCredential(accountName, sharedKeyCredentialOrUserDelegationKey);
    }
    if (sharedKeyCredential !== undefined) {
        return generateFileSASQueryParametersDefault(fileSASSignatureValues, sharedKeyCredential);
    }
    else {
        if (version >= "2025-07-05") {
            return generateFileSASQueryParametersUDK20250705(fileSASSignatureValues, userDelegationKeyCredential, accountName);
        }
        else {
            throw new RangeError("'version' must be >= '2025-07-05' when generating user delegation SAS using user delegation key.");
        }
    }
}
export function generateFileSASQueryParametersDefault(fileSASSignatureValues, sharedKeyCredential) {
    if (!fileSASSignatureValues.identifier &&
        !(fileSASSignatureValues.permissions && fileSASSignatureValues.expiresOn)) {
        throw new RangeError("Must provide 'permissions' and 'expiresOn' for File SAS generation when 'identifier' is not provided.");
    }
    const version = fileSASSignatureValues.version ? fileSASSignatureValues.version : SERVICE_VERSION;
    let resource = "s";
    if (fileSASSignatureValues.filePath) {
        resource = "f";
    }
    let verifiedPermissions;
    // Calling parse and toString guarantees the proper ordering and throws on invalid characters.
    if (fileSASSignatureValues.permissions) {
        if (fileSASSignatureValues.filePath) {
            verifiedPermissions = FileSASPermissions.parse(fileSASSignatureValues.permissions.toString()).toString();
        }
        else {
            verifiedPermissions = ShareSASPermissions.parse(fileSASSignatureValues.permissions.toString()).toString();
        }
    }
    // Signature is generated on the un-url-encoded values.
    const stringToSign = [
        verifiedPermissions,
        fileSASSignatureValues.startsOn
            ? truncatedISO8061Date(fileSASSignatureValues.startsOn, false)
            : "",
        fileSASSignatureValues.expiresOn
            ? truncatedISO8061Date(fileSASSignatureValues.expiresOn, false)
            : "",
        getCanonicalName(sharedKeyCredential.accountName, fileSASSignatureValues.shareName, fileSASSignatureValues.filePath),
        fileSASSignatureValues.identifier,
        fileSASSignatureValues.ipRange ? ipRangeToString(fileSASSignatureValues.ipRange) : "",
        fileSASSignatureValues.protocol,
        version,
        fileSASSignatureValues.cacheControl,
        fileSASSignatureValues.contentDisposition,
        fileSASSignatureValues.contentEncoding,
        fileSASSignatureValues.contentLanguage,
        fileSASSignatureValues.contentType,
    ].join("\n");
    const signature = sharedKeyCredential.computeHMACSHA256(stringToSign);
    return {
        sasQueryParameters: new SASQueryParameters(version, signature, verifiedPermissions, undefined, undefined, fileSASSignatureValues.protocol, fileSASSignatureValues.startsOn, fileSASSignatureValues.expiresOn, fileSASSignatureValues.ipRange, fileSASSignatureValues.identifier, resource, fileSASSignatureValues.cacheControl, fileSASSignatureValues.contentDisposition, fileSASSignatureValues.contentEncoding, fileSASSignatureValues.contentLanguage, fileSASSignatureValues.contentType),
        stringToSign: stringToSign,
    };
}
export function generateFileSASQueryParametersUDK20250705(fileSASSignatureValues, userDelegationKeyCredential, accountName) {
    if (!(fileSASSignatureValues.permissions && fileSASSignatureValues.expiresOn)) {
        throw new RangeError("Must provide 'permissions' and 'expiresOn' for File SAS generation when generating user delegation SAS.");
    }
    const version = fileSASSignatureValues.version ? fileSASSignatureValues.version : SERVICE_VERSION;
    let resource = "s";
    if (fileSASSignatureValues.filePath) {
        resource = "f";
    }
    let verifiedPermissions;
    // Calling parse and toString guarantees the proper ordering and throws on invalid characters.
    if (fileSASSignatureValues.permissions) {
        if (fileSASSignatureValues.filePath) {
            verifiedPermissions = FileSASPermissions.parse(fileSASSignatureValues.permissions.toString()).toString();
        }
        else {
            verifiedPermissions = ShareSASPermissions.parse(fileSASSignatureValues.permissions.toString()).toString();
        }
    }
    // Signature is generated on the un-url-encoded values.
    const stringToSign = [
        verifiedPermissions,
        fileSASSignatureValues.startsOn
            ? truncatedISO8061Date(fileSASSignatureValues.startsOn, false)
            : "",
        fileSASSignatureValues.expiresOn
            ? truncatedISO8061Date(fileSASSignatureValues.expiresOn, false)
            : "",
        getCanonicalName(accountName, fileSASSignatureValues.shareName, fileSASSignatureValues.filePath),
        userDelegationKeyCredential.userDelegationKey.signedObjectId,
        userDelegationKeyCredential.userDelegationKey.signedTenantId,
        userDelegationKeyCredential.userDelegationKey.signedStartsOn
            ? truncatedISO8061Date(userDelegationKeyCredential.userDelegationKey.signedStartsOn, false)
            : "",
        userDelegationKeyCredential.userDelegationKey.signedExpiresOn
            ? truncatedISO8061Date(userDelegationKeyCredential.userDelegationKey.signedExpiresOn, false)
            : "",
        userDelegationKeyCredential.userDelegationKey.signedService,
        userDelegationKeyCredential.userDelegationKey.signedVersion,
        userDelegationKeyCredential.userDelegationKey.signedDelegatedUserTenantId, // shared key delegation signed tenant id.
        fileSASSignatureValues.delegatedUserObjectId,
        fileSASSignatureValues.ipRange ? ipRangeToString(fileSASSignatureValues.ipRange) : "",
        fileSASSignatureValues.protocol,
        version,
        fileSASSignatureValues.cacheControl,
        fileSASSignatureValues.contentDisposition,
        fileSASSignatureValues.contentEncoding,
        fileSASSignatureValues.contentLanguage,
        fileSASSignatureValues.contentType,
    ].join("\n");
    const signature = userDelegationKeyCredential.computeHMACSHA256(stringToSign);
    return {
        sasQueryParameters: new SASQueryParameters(version, signature, verifiedPermissions, undefined, undefined, fileSASSignatureValues.protocol, fileSASSignatureValues.startsOn, fileSASSignatureValues.expiresOn, fileSASSignatureValues.ipRange, fileSASSignatureValues.identifier, resource, fileSASSignatureValues.cacheControl, fileSASSignatureValues.contentDisposition, fileSASSignatureValues.contentEncoding, fileSASSignatureValues.contentLanguage, fileSASSignatureValues.contentType, userDelegationKeyCredential.userDelegationKey, fileSASSignatureValues.delegatedUserObjectId),
        stringToSign: stringToSign,
    };
}
function getCanonicalName(accountName, shareName, filePath) {
    // Share: "/file/account/sharename"
    // File:  "/file/account/sharename/filename"
    // File:  "/file/account/sharename/directoryname/filename"
    const elements = [`/file/${accountName}/${shareName}`];
    if (filePath) {
        elements.push(`/${filePath}`);
    }
    return elements.join("");
}
//# sourceMappingURL=FileSASSignatureValues.js.map