var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
    var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
    else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
    if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __param = (this && this.__param) || function (paramIndex, decorator) {
    return function (target, key) { decorator(target, key, paramIndex); }
};
/**
 * Copyright (C) 2024 Hedera Hashgraph, LLC
 *
 * Licensed under the Apache License, Version 2.0 (the ""License"");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an ""AS IS"" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */
import * as constants from './constants.js';
import { Helm } from './helm.js';
import chalk from 'chalk';
import { SoloError } from './errors.js';
import { SoloLogger } from './logging.js';
import { inject, injectable } from 'tsyringe-neo';
import { patchInject } from './container_helper.js';
let ChartManager = class ChartManager {
    helm;
    logger;
    constructor(helm, logger) {
        this.helm = helm;
        this.logger = logger;
        this.helm = patchInject(helm, Helm, this.constructor.name);
        this.logger = patchInject(logger, SoloLogger, this.constructor.name);
    }
    /**
     * Setup chart repositories
     *
     * This must be invoked before calling other methods
     *
     * @param repoURLs - a map of name and chart repository URLs
     * @param force - whether or not to update the repo
     * @returns the urls
     */
    async setup(repoURLs = constants.DEFAULT_CHART_REPO, force = true) {
        try {
            const forceUpdateArg = force ? '--force-update' : '';
            const promises = [];
            for (const [name, url] of repoURLs.entries()) {
                promises.push(this.addRepo(name, url, forceUpdateArg));
            }
            return await Promise.all(promises); // urls
        }
        catch (e) {
            throw new SoloError(`failed to setup chart repositories: ${e.message}`, e);
        }
    }
    async addRepo(name, url, forceUpdateArg) {
        this.logger.debug(`Adding repo ${name} -> ${url}`, { repoName: name, repoURL: url });
        await this.helm.repo('add', name, url, forceUpdateArg);
        return url;
    }
    /** List available clusters */
    async getInstalledCharts(namespaceName) {
        try {
            if (!namespaceName) {
                return await this.helm.list('--all-namespaces --no-headers | awk \'{print $1 " [" $9"]"}\'');
            }
            return await this.helm.list(`-n ${namespaceName}`, '--no-headers | awk \'{print $1 " [" $9"]"}\'');
        }
        catch (e) {
            this.logger.showUserError(e);
        }
        return [];
    }
    async install(namespaceName, chartReleaseName, chartPath, version, valuesArg = '') {
        try {
            const isInstalled = await this.isChartInstalled(namespaceName, chartReleaseName);
            if (!isInstalled) {
                const versionArg = version ? `--version ${version}` : '';
                const namespaceArg = namespaceName ? `-n ${namespaceName} --create-namespace` : '';
                this.logger.debug(`> installing chart:${chartPath}`);
                await this.helm.install(`${chartReleaseName} ${chartPath} ${versionArg} ${namespaceArg} ${valuesArg}`);
                this.logger.debug(`OK: chart is installed: ${chartReleaseName} (${chartPath})`);
            }
            else {
                this.logger.debug(`OK: chart is already installed:${chartReleaseName} (${chartPath})`);
            }
        }
        catch (e) {
            throw new SoloError(`failed to install chart ${chartReleaseName}: ${e.message}`, e);
        }
        return true;
    }
    async isChartInstalled(namespaceName, chartReleaseName) {
        this.logger.debug(`> checking if chart is installed [ chart: ${chartReleaseName}, namespace: ${namespaceName} ]`);
        const charts = await this.getInstalledCharts(namespaceName);
        return charts.some(item => item.startsWith(chartReleaseName));
    }
    async uninstall(namespaceName, chartReleaseName) {
        try {
            const isInstalled = await this.isChartInstalled(namespaceName, chartReleaseName);
            if (isInstalled) {
                this.logger.debug(`uninstalling chart release: ${chartReleaseName}`);
                await this.helm.uninstall(`-n ${namespaceName} ${chartReleaseName}`);
                this.logger.debug(`OK: chart release is uninstalled: ${chartReleaseName}`);
            }
            else {
                this.logger.debug(`OK: chart release is already uninstalled: ${chartReleaseName}`);
            }
        }
        catch (e) {
            throw new SoloError(`failed to uninstall chart ${chartReleaseName}: ${e.message}`, e);
        }
        return true;
    }
    async upgrade(namespaceName, chartReleaseName, chartPath, version = '', valuesArg = '') {
        const versionArg = version ? `--version ${version}` : '';
        try {
            this.logger.debug(chalk.cyan('> upgrading chart:'), chalk.yellow(`${chartReleaseName}`));
            await this.helm.upgrade(`-n ${namespaceName} ${chartReleaseName} ${chartPath} ${versionArg} --reuse-values ${valuesArg}`);
            this.logger.debug(chalk.green('OK'), `chart '${chartReleaseName}' is upgraded`);
        }
        catch (e) {
            throw new SoloError(`failed to upgrade chart ${chartReleaseName}: ${e.message}`, e);
        }
        return true;
    }
};
ChartManager = __decorate([
    injectable(),
    __param(0, inject(Helm)),
    __param(1, inject(SoloLogger)),
    __metadata("design:paramtypes", [Helm,
        SoloLogger])
], ChartManager);
export { ChartManager };
//# sourceMappingURL=chart_manager.js.map