import { BasicAuthStrategy } from '../auth/basic.js';
import { resolveAuthStrategy } from '../auth/resolve.js';
import { WebDavClient } from '../clients/webdav.js';
import { createOcapiClient } from '../clients/ocapi.js';
import { createTlsDispatcher } from '../clients/tls-dispatcher.js';
/**
 * Represents a connection to a B2C Commerce instance.
 *
 * Provides lazy-loaded, typed API clients for WebDAV and OCAPI operations.
 * Authentication is handled automatically based on the configured credentials.
 *
 * @example
 * // From configuration (recommended)
 * import { resolveConfig } from '@salesforce/b2c-tooling-sdk/config';
 *
 * const config = resolveConfig({
 *   clientId: process.env.SFCC_CLIENT_ID,
 *   clientSecret: process.env.SFCC_CLIENT_SECRET,
 * });
 * const instance = config.createB2CInstance();
 *
 * // WebDAV uses Basic auth if available, falls back to OAuth
 * await instance.webdav.mkcol('Cartridges/v1');
 *
 * // OCAPI always uses OAuth
 * const { data } = await instance.ocapi.GET('/sites', {});
 */
export class B2CInstance {
    config;
    auth;
    _webdav;
    _ocapi;
    /**
     * Creates a new B2CInstance.
     *
     * @param config - Instance configuration (hostname, code version)
     * @param auth - Authentication configuration
     */
    constructor(config, auth) {
        this.config = config;
        this.auth = auth;
    }
    /**
     * The hostname to use for WebDAV operations.
     * Falls back to main hostname if not specified.
     */
    get webdavHostname() {
        return this.config.webdavHostname || this.config.hostname;
    }
    /**
     * WebDAV client for file operations.
     *
     * Uses Basic auth if username/password are configured,
     * otherwise falls back to OAuth.
     *
     * @example
     * await instance.webdav.mkcol('Cartridges/v1');
     * await instance.webdav.put('Cartridges/v1/app.zip', content);
     * const entries = await instance.webdav.propfind('Cartridges');
     */
    get webdav() {
        if (!this._webdav) {
            // Create TLS dispatcher if TLS options are configured
            const dispatcher = this.config.tlsOptions ? createTlsDispatcher(this.config.tlsOptions) : undefined;
            this._webdav = new WebDavClient(this.webdavHostname, this.getWebDavAuthStrategy(), {
                dispatcher,
            });
        }
        return this._webdav;
    }
    /**
     * OCAPI Data API client.
     *
     * Returns the openapi-fetch client directly with full type safety.
     * Always uses OAuth authentication.
     *
     * @example
     * const { data, error } = await instance.ocapi.GET('/sites', {});
     * const { data, error } = await instance.ocapi.PATCH('/code_versions/{code_version_id}', {
     *   params: { path: { code_version_id: 'v1' } },
     *   body: { active: true }
     * });
     */
    get ocapi() {
        if (!this._ocapi) {
            this._ocapi = createOcapiClient(this.config.hostname, this.getOAuthStrategy());
        }
        return this._ocapi;
    }
    /**
     * Gets the auth strategy for WebDAV operations.
     * Uses authMethods to determine priority, defaulting to basic then OAuth methods.
     */
    getWebDavAuthStrategy() {
        // For WebDAV, default priority is basic first, then OAuth methods
        const webdavMethods = this.auth.authMethods || ['basic', 'client-credentials', 'implicit'];
        // If basic auth is allowed and configured, use it directly
        if (webdavMethods.includes('basic') && this.auth.basic) {
            return new BasicAuthStrategy(this.auth.basic.username, this.auth.basic.password);
        }
        // Otherwise try OAuth methods
        return this.getOAuthStrategy();
    }
    /**
     * Gets the OAuth auth strategy based on allowed methods and available credentials.
     * Uses resolveAuthStrategy to automatically select the best OAuth method.
     *
     * @throws Error if no valid OAuth method is available
     */
    getOAuthStrategy() {
        if (!this.auth.oauth) {
            throw new Error('OAuth credentials required. Provide at least clientId.');
        }
        // Build credentials for resolution
        const credentials = {
            clientId: this.auth.oauth.clientId,
            clientSecret: this.auth.oauth.clientSecret,
            scopes: this.auth.oauth.scopes,
            accountManagerHost: this.auth.oauth.accountManagerHost,
        };
        // Filter to only OAuth methods (client-credentials, implicit)
        const oauthMethods = (this.auth.authMethods || ['client-credentials', 'implicit']).filter((m) => m === 'client-credentials' || m === 'implicit');
        if (oauthMethods.length === 0) {
            throw new Error('No OAuth methods allowed. Check authMethods configuration.');
        }
        return resolveAuthStrategy(credentials, { allowedMethods: oauthMethods });
    }
}
//# sourceMappingURL=index.js.map