import { alchemy } from "../alchemy.js";
import { Resource } from "../resource.js";
import { logger } from "../util/logger.js";
import { UpstashApi } from "./api.js";
import { UpstashError } from "./error.js";
/**
 * Create and manage Upstash Redis databases
 *
 * @example
 * // Create a basic Redis database in us-east-1:
 * const redis = await UpstashRedis("my-redis", {
 *   name: "my-redis",
 *   primaryRegion: "us-east-1"
 * });
 *
 * @example
 * // Create a Redis database with read replicas:
 * const redis = await UpstashRedis("my-redis", {
 *   name: "my-redis",
 *   primaryRegion: "us-east-1",
 *   readRegions: ["us-west-1", "us-west-2"]
 * });
 *
 * @example
 * // Create a Redis database with a monthly budget:
 * const redis = await UpstashRedis("my-redis", {
 *   name: "my-redis",
 *   primaryRegion: "us-east-1",
 *   budget: 100
 * });
 */
export const UpstashRedis = Resource("upstash::Redis", async function (id, props) {
    const api = new UpstashApi({
        apiKey: props.apiKey,
        email: props.email,
    });
    const databaseName = props.name ?? this.output?.name ?? this.scope.createPhysicalName(id);
    if (this.phase === "delete") {
        await deleteRedisDatabase(api, this.output.id);
        return this.destroy();
    }
    const eviction = props.eviction ?? false;
    // @ts-expect-error This is overridden during update/create
    let database = {};
    if (this.phase === "update") {
        // Update name if changed
        if (databaseName !== this.output.name) {
            await renameRedisDatabase(api, this.output.id, databaseName);
        }
        // Update read regions if changed
        if (JSON.stringify(props.readRegions) !==
            JSON.stringify(this.output.readRegions)) {
            await updateRedisReadRegions(api, this.output.id, props.readRegions || []);
        }
        // Handle eviction setting if changed
        if (props.eviction !== undefined &&
            props.eviction !== this.output.eviction) {
            await setRedisEviction(api, this.output.id, props.eviction);
        }
        // Get updated database info
        database = await getRedisDatabase(api, this.output.id);
    }
    if (this.phase === "create") {
        database = await createRedisDatabase(api, {
            budget: props.budget,
            name: databaseName,
            primary_region: props.primaryRegion,
            read_regions: props.readRegions,
            region: "global",
            tls: true,
        });
        if (eviction) {
            await setRedisEviction(api, database.database_id, eviction);
        }
    }
    return this.create({
        id: database.database_id,
        name: database.database_name,
        databaseType: database.database_type,
        region: database.region,
        port: database.port,
        createdAt: database.creation_time,
        state: database.state,
        password: alchemy.secret(database.password),
        userEmail: database.user_email,
        endpoint: database.endpoint,
        tls: database.tls,
        restToken: alchemy.secret(database.rest_token),
        readOnlyRestToken: alchemy.secret(database.read_only_rest_token),
        primaryRegion: props.primaryRegion,
        readRegions: props.readRegions,
        budget: props.budget,
        eviction: props.eviction ?? false,
    });
});
/**
 * Delete a Redis database
 *
 * @param api Upstash API client
 * @param databaseId ID of the database to delete
 */
export async function deleteRedisDatabase(api, databaseId) {
    const response = await api.delete(`/redis/database/${databaseId}`);
    if (!response.ok && response.status !== 404) {
        throw new UpstashError(`Error deleting database: ${response.statusText}`, response.status, response);
    }
}
/**
 * Rename a Redis database
 *
 * @param api Upstash API client
 * @param databaseId ID of the database to rename
 * @param name New name for the database
 */
export async function renameRedisDatabase(api, databaseId, name) {
    const response = await api.post(`/redis/rename/${databaseId}`, {
        name,
    });
    if (!response.ok) {
        throw new UpstashError(`API error updating name: ${response.statusText}`, response.status, response);
    }
}
/**
 * Update read regions for a Redis database
 *
 * @param api Upstash API client
 * @param databaseId ID of the database to update
 * @param readRegions Array of read regions
 */
export async function updateRedisReadRegions(api, databaseId, readRegions) {
    const response = await api.post(`/redis/update-regions/${databaseId}`, {
        read_regions: readRegions,
    });
    if (!response.ok) {
        throw new UpstashError(`API error updating regions: ${response.statusText}`, response.status, response);
    }
}
/**
 * Enable or disable eviction for a Redis database
 *
 * @param api Upstash API client
 * @param databaseId ID of the database to update
 * @param enable Whether to enable or disable eviction
 */
export async function setRedisEviction(api, databaseId, enable) {
    const evictionEndpoint = enable ? "enable-eviction" : "disable-eviction";
    const response = await api.post(`/redis/${evictionEndpoint}/${databaseId}`, {});
    if (!response.ok) {
        logger.warn(`API error updating eviction (status: ${response.status}): ${response.statusText}. (Eviction may already be set)`);
    }
}
/**
 * Get information about a Redis database
 *
 * @param api Upstash API client
 * @param databaseId ID of the database to get information about
 * @returns Database information
 */
export async function getRedisDatabase(api, databaseId) {
    const response = await api.get(`/redis/database/${databaseId}`);
    if (!response.ok) {
        throw new UpstashError(`API error: ${response.statusText}`, response.status, response);
    }
    return await response.json();
}
/**
 * Create a new Redis database
 *
 * @param api Upstash API client
 * @param params Parameters for the new database
 * @returns Created database information
 */
export async function createRedisDatabase(api, params) {
    const response = await api.post("/redis/database", params);
    if (!response.ok) {
        throw new UpstashError(`API error creating database: ${response.statusText}`, response.status, response);
    }
    return await response.json();
}
//# sourceMappingURL=redis.js.map