"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.AccountHelper = void 0;
const workbench_core_datasets_1 = require("@aws/workbench-core-datasets");
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
const lodash_1 = __importDefault(require("lodash"));
const setup_1 = __importDefault(require("../setup"));
class AccountHelper {
    constructor() {
        const setup = setup_1.default.getSetup();
        this._settings = setup.getSettings();
        this._awsSdk = setup.getMainAwsClient();
    }
    // TODO: Replace with Accounts list API call when it is available
    async listOnboardedAccounts() {
        const queryParams = {
            index: 'getResourceByCreatedAt',
            key: { name: 'resourceType', value: 'account' }
        };
        const response = await this._awsSdk.helpers.ddb.query(queryParams).execute();
        let accounts = [];
        if (response && response.Items) {
            accounts = response.Items.map((item) => {
                return item;
            });
        }
        return accounts;
    }
    async deleteDdbRecords(accountId, awsAccountId) {
        await this._awsSdk.helpers.ddb.delete({ pk: `ACC#${accountId}`, sk: `ACC#${accountId}` }).execute();
        await this._awsSdk.helpers.ddb.delete({ pk: `AWSACC#${awsAccountId}`, sk: `ACC#${accountId}` }).execute();
    }
    async verifyBusAllowsAccount(awsAccountId) {
        const busName = 'default';
        const busRuleName = 'RouteHostEvents';
        const describeRuleParams = { Name: busRuleName, EventBusName: busName };
        // Rule will always exist since other integ tests require an active hosting account onboarded
        const busRule = await this._awsSdk.clients.eventBridge.describeRule(describeRuleParams);
        return lodash_1.default.includes(JSON.parse(busRule.EventPattern).account, awsAccountId);
    }
    async removeBusPermissions(awsAccountId) {
        const busName = 'default';
        const params = {
            Action: 'events:PutEvents',
            EventBusName: busName,
            Principal: awsAccountId,
            StatementId: `Allow-main-account-to-get-${awsAccountId}-events`
        };
        // Remove permission for main account to receive hosting account events
        await this._awsSdk.clients.eventBridge.removePermission(params);
        const busRuleName = 'RouteHostEvents';
        const describeRuleParams = { Name: busRuleName, EventBusName: busName };
        // Rule will always exist since other integ tests require an active hosting account onboarded
        const busRule = await this._awsSdk.clients.eventBridge.describeRule(describeRuleParams);
        const putRuleParams = {
            Name: busRuleName,
            EventPattern: JSON.stringify({
                account: lodash_1.default.difference(JSON.parse(busRule.EventPattern).account, [awsAccountId]),
                source: [{ 'anything-but': ['aws.config', 'aws.cloudtrail', 'aws.ssm', 'aws.tag'] }],
                'detail-type': [{ 'anything-but': 'AWS API Call via CloudTrail' }]
            }),
            EventBusName: busName
        };
        // Update rule for main account event bus
        await this._awsSdk.clients.eventBridge.putRule(putRuleParams);
    }
    async removeAccountFromKeyPolicy(awsAccountId) {
        const mainAcctS3ArtifactEncryptionArn = this._settings.get('S3ArtifactEncryptionKeyOutputCC25B0CD');
        const mainAcctS3DatasetsEncryptionArn = this._settings.get('S3DatasetsEncryptionKeyOutput05C7794D');
        const mainAcctEncryptionArnList = [mainAcctS3ArtifactEncryptionArn, mainAcctS3DatasetsEncryptionArn];
        await Promise.all(lodash_1.default.map(mainAcctEncryptionArnList, async (mainAcctEncryptionArn) => {
            const keyId = mainAcctEncryptionArn.split('/').pop();
            const keyPolicyResponse = await this._awsSdk.clients.kms.getKeyPolicy({
                KeyId: keyId,
                PolicyName: 'default'
            });
            let keyPolicy = aws_iam_1.PolicyDocument.fromJson(JSON.parse(keyPolicyResponse.Policy));
            keyPolicy = workbench_core_datasets_1.IamHelper.removePrincipalFromStatement(keyPolicy, 'main-key-share-statement', `arn:aws:iam::${awsAccountId}:root`);
            const putPolicyParams = {
                KeyId: keyId,
                PolicyName: 'default',
                Policy: JSON.stringify(keyPolicy.toJSON())
            };
            // Update key policy
            await this._awsSdk.clients.kms.putKeyPolicy(putPolicyParams);
        }));
    }
    async removeAccountFromBucketPolicy(awsAccountId) {
        const bucketName = this._settings.get('S3BucketArtifactsArnOutput').split(':').pop();
        const bucketPolicyResponse = await this._awsSdk.clients.s3.getBucketPolicy({
            Bucket: bucketName,
            ExpectedBucketOwner: process.env.MAIN_ACCT_ID
        });
        let bucketPolicy;
        bucketPolicy = aws_iam_1.PolicyDocument.fromJson(JSON.parse(bucketPolicyResponse.Policy));
        bucketPolicy = workbench_core_datasets_1.IamHelper.removePrincipalFromStatement(bucketPolicy, 'List:environment-files', `arn:aws:iam::${awsAccountId}:root`);
        bucketPolicy = workbench_core_datasets_1.IamHelper.removePrincipalFromStatement(bucketPolicy, 'Get:environment-files', `arn:aws:iam::${awsAccountId}:root`);
        const putPolicyParams = {
            Bucket: bucketName,
            Policy: JSON.stringify(bucketPolicy.toJSON()),
            AccountId: process.env.MAIN_ACCT_ID
        };
        // Update bucket policy
        await this._awsSdk.clients.s3.putBucketPolicy(putPolicyParams);
    }
    async deOnboardAccount(awsAccountId) {
        // Undo all operations that happen in: hostingAccountLifecycleService.createAccount()
        // Update main account default event bus to remove hosting account state change events
        await this.removeBusPermissions(awsAccountId);
        // Remove account to artifactBucket's bucket policy
        await this.removeAccountFromBucketPolicy(awsAccountId);
        // Update main account encryption key policy
        await this.removeAccountFromKeyPolicy(awsAccountId);
    }
}
exports.AccountHelper = AccountHelper;
//# sourceMappingURL=accountHelper.js.map